> For the complete documentation index, see [llms.txt](https://developer.harness.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developer.harness.io/continuous-delivery/use-continuous-delivery/cd-building-blocks/environments/create-environments.md).

# Create environments

Environments represent your deployment targets (QA, Prod, etc). Each environment contains one or more **Infrastructure Definitions** that list your target clusters, hosts, namespaces, etc.

### Create an environment <a href="#create-an-environment" id="create-an-environment"></a>

You can create environments from:

* Within a pipeline
* Outside a pipeline
* An account
* An Organization

{% tabs %}
{% tab title="Within a pipeline" %}
To create an environment from inside of a pipeline, select **New Environment** in the **Infrastructure** tab of a new CD stage.

![](/files/1KxFASqeBcsFgTkioMSZ)
{% endtab %}

{% tab title="Outside a pipeline" %}
To create an Environment from outside of a pipeline, you use **Environments** in the navigation pane.

![](/files/40ymTIbYzHU0qTfvdabx)
{% endtab %}

{% tab title="From organization or account" %}
You can create an environment and provide infrastructure definitions at an account or organization level from the Harness UI, using APIs or Terraform.

{% tabs %}
{% tab title="Pipeline Studio" %}
To create an environment at an account or organization level, go to **Organization Resources** **>Environments**.

![](/files/T0newZIWrhKeqK8O6pO4)

Expand the section below to see a sample account level environment YAML.

<details>

<summary>Account level environment YAML</summary>

```
environment:
  name: dev
  identifier: dev
  description: account wide dev environment
  tags:
    status: non-regulated
  type: PreProduction
  variables:
    - name: port
      type: String
      value: "8080"
      description: ""
    - name: namespace
      type: String
      value: <+service.name>-dev
      description: "namespace environment variable"
```

</details>

Expand the section below to see a sample account level infrastructure definition YAML.

<details>

<summary>Account level infrastructure definition YAML</summary>

```
infrastructureDefinition:
  name: dev-k8s
  identifier: dev
  description: development Kubernetes cluster
  tags: {}
  environmentRef: dev
  deploymentType: Kubernetes
  type: KubernetesDirect
  spec:
    connectorRef: account.Harness_Kubernetes_Cluster
    namespace: <+service.name>-dev
    releaseName: release-<+INFRA_KEY_SHORT_ID>
  allowSimultaneousDeployments: false
```

</details>

Expand the section below to see a sample organization level environment YAML.

<details>

<summary>Organization level environment YAML</summary>

```
environment:
  name: prod
  identifier: prod
  description: production environment for the organization
  tags:
    status: regulated
  type: Production
  orgIdentifier: default
  variables:
    - name: namespace
      type: String
      value: <+service.name>-prod
      description: "namespace for prod environment"
    - name: port
      type: String
      value: "8080"
      description: "port for prod environment"
```

</details>

Expand the section below to see a sample organization level infrastructure definition YAML.

<details>

<summary>Organization level infrastructure definition YAML</summary>

```
infrastructureDefinition:
  name: prod-k8s
  identifier: prodk8s
  description: production kubernetes cluster
  tags: {}
  orgIdentifier: default
  environmentRef: prod
  deploymentType: Kubernetes
  type: KubernetesDirect
  spec:
    connectorRef: account.Harness_Kubernetes_Cluster
    namespace: production
    releaseName: release-<+INFRA_KEY_SHORT_ID>
  allowSimultaneousDeployments: false
```

</details>
{% endtab %}

{% tab title="API" %}
For information about creating an environment API, go to [create an environment](https://apidocs.harness.io/tag/Environments#operation/createEnvironmentV2).

For information about creating infrastructure definition API, go to [create an infrastructure in an environment](https://apidocs.harness.io/tag/Infrastructures#operation/createInfrastructure).

The `orgIdentifier` and `projectIdentifier` field definitions are optional, and depend on where you want to create the environment. For example, if you create an environment at an account level, you will not need org or project identifiers in the post API call payload.
{% endtab %}

{% tab title="Terraform" %}
For information about creating a Harness platform environment, go to [harness\_platform\_environment (Resource)](https://registry.terraform.io/providers/harness/harness/latest/docs/resources/platform_environment).

Expand the section below to see a sample platform environment in Terraform.

<details>

<summary>Harness platform environment</summary>

```
resource "harness_platform_environment" "example" {
  identifier = "identifier"
  name       = "name"
  org_id     = "org_id"
  project_id = "project_id"
  tags       = ["foo:bar", "baz"]
  type       = "PreProduction"

  ## ENVIRONMENT V2 Update
  ## The YAML is needed if you want to define the Environment Variables and Overrides for the environment
  ## Not Mandatory for Environment Creation nor Pipeline Usage

  yaml = <<-EOT
               environment:
         name: name
         identifier: identifier
         orgIdentifier: org_id
         projectIdentifier: project_id
         type: PreProduction
         tags:
           foo: bar
           baz: ""
         variables:
           - name: envVar1
             type: String
             value: v1
             description: ""
           - name: envVar2
             type: String
             value: v2
             description: ""
         overrides:
           manifests:
             - manifest:
                 identifier: manifestEnv
                 type: Values
                 spec:
                   store:
                     type: Git
                     spec:
                       connectorRef: <+input>
                       gitFetchType: Branch
                       paths:
                         - file1
                       repoName: <+input>
                       branch: master
           configFiles:
             - configFile:
                 identifier: configFileEnv
                 spec:
                   store:
                     type: Harness
                     spec:
                       files:
                         - account:/Add-ons/svcOverrideTest
                       secretFiles: []
      EOT
}
```

</details>

For information about creating a Harness platform infrastructure definition, go to [harness\_platform\_infrastructure (Resource)](https://registry.terraform.io/providers/harness/harness/latest/docs/resources/platform_infrastructure).

Expand the section below to see a sample platform infrastructure definition in Terraform.

<details>

<summary>Harness platform infrastructure definition</summary>

```
resource "harness_platform_infrastructure" "example" {
  identifier      = "identifier"
  name            = "name"
  org_id          = "orgIdentifer"
  project_id      = "projectIdentifier"
  env_id          = "environmentIdentifier"
  type            = "KubernetesDirect"
  deployment_type = "Kubernetes"
  yaml            = <<-EOT
        infrastructureDefinition:
         name: name
         identifier: identifier
         description: ""
         tags:
           asda: ""
         orgIdentifier: orgIdentifer
         projectIdentifier: projectIdentifier
         environmentRef: environmentIdentifier
         deploymentType: Kubernetes
         type: KubernetesDirect
         spec:
          connectorRef: account.gfgf
          namespace: asdasdsa
          releaseName: release-<+INFRA_KEY_SHORT_ID>
          allowSimultaneousDeployments: false
      EOT
}
```

</details>

The `org_id` and `project_id` field definitions are optional, and depend on where you want to create the environment. For example, if you create an environment at an account level, you will not need org or project identifiers.
{% endtab %}
{% endtabs %}
{% endtab %}
{% endtabs %}

### Define the environment configuration <a href="#define-the-environment-configuration" id="define-the-environment-configuration"></a>

In the environment **Configuration**, you can manage the **Name**, **Description**, **Tags**, and **Environment Type** of the environment.

![](/files/oFeMtSlueVrO8Kk0Jfw7)

You can also set default manifests, specifications, config files, and variables to use whenever Harness deploys a service to this environment.

For example, a stage has a Kubernetes service with a manifest but whenever that service is deployed to the **QA** environment, the manifest in that environment's **Configuration** overwrites the namespace of with the manifest in the service with `QA`.

### Create service overrides <a href="#create-service-overrides" id="create-service-overrides"></a>

Service overrides are different from **Environment Configuration** in the following ways:

* Environment **Configuration**: applies to every service that is used with the environment.
* Environment **Service Overrides**: applies to specific services you select. Whenever that service is used with that environment, the **Service Override** is applied.

#### Override priority <a href="#override-priority" id="override-priority"></a>

When you are using environment configuration and service override to override service settings, it's important to understand the priority of the overrides.

The priority from top to bottom is:

1. Environment service overrides
2. Environment configuration
3. Service settings

![](/files/YPjYhiUXOIl8A8PzEA8C)

#### Overriding values.yaml <a href="#overriding-valuesyaml" id="overriding-valuesyaml"></a>

You can specify values YAML files at the environment's **Service Overrides** and **Configuration**, and the service itself.

Here is an example of specifying it at the environment's **Configuration**:

![](/files/du2fEEZcbgWBm7HzNPkz)

When you have a values yaml file at two or more of the environment **Service Overrides**, **Environment Configuration**, and the service itself, Harness merges the files into a single values YAML for deployment. This merging is performed at pipeline execution runtime.

Overriding occurs when the higher priority setting has the same `name:value` pair as a lower priority setting.

Let's look at two examples.

#### Merging values.yaml name:value pairs <a href="#merging-valuesyaml-namevalue-pairs" id="merging-valuesyaml-namevalue-pairs"></a>

An environment's **Service Overrides** values YAML has the name:value pair `servicePort: 80` but no `replicas` name:value.

A service's **Service Definition** has a values YAML with `replicas: 2` but no `servicePort` name:value.

At runtime, the two values YAML files are merged into one.

The `servicePort: 80` from the environment **Service Overrides** values YAML is merged with the **Service Definition**'s `replicas: 2` in the values YAML:

![](/files/mEZ3kQVedSV7nn27Lb0A)

#### Fully overriding values.yaml name:value pairs <a href="#fully-overriding-valuesyaml-namevalue-pairs" id="fully-overriding-valuesyaml-namevalue-pairs"></a>

An environment's **Service Overrides** values YAML has the name:value pairs `replicas: 2` and `servicePort: 80`.

A service's **Service Definition** has a values YAML with `replicas: 4` and `servicePort: 8080`.

At runtime, the name:value pairs from the environment **Service Overrides** values YAML fully override the service values YAML. The `replicas: 2` and `servicePort: 80` from the environment **Service Overrides** are used.

![](/files/0PUff5McfeFFwZcalwyQ)

#### Fully overriding config files and variables <a href="#fully-overriding-config-files-and-variables" id="fully-overriding-config-files-and-variables"></a>

Config files are a black box that can contain multiple formats and content, such as YAML, JSON, plain text, etc. Consequently, they cannot be overridden like Values YAML files.

Variables cannot be partially overridden either. They are completely replaced.

When you have **Config files** at two or more of the environment **Service Overrides**, **Configuration**, and the service itself, the standard override priority is applied.

When you have **Variables** with the same name at two or more of the environment **Service Overrides**, **Configuration**, and the service itself, the standard override priority is applied.

### Add infrastructure definitions <a href="#add-infrastructure-definitions" id="add-infrastructure-definitions"></a>

Infrastructure definitions represent an environment's infrastructures physically. They are the actual clusters, hosts, namespaces, etc, where you are deploying a service.

An environment can have multiple **Infrastructure Definitions**.

![](/files/PbLWlqAFigw7Z2YH84ZQ)

When you select an environment in a stage, you can select the **Infrastructure Definition** to use for that stage.

![](/files/J41wRpf9z7jiGuborTbU)

### Propagating environments through multiple stages <a href="#propagating-environments-through-multiple-stages" id="propagating-environments-through-multiple-stages"></a>

When modeling multiple Deploy stages in a pipeline, you can propagate the environment and infrastructure definition selected in one stage to one or more subsequent stages.

When you propagate an environment, you can either use the same infrastructure definition that was used in the parent stage or you can [select a different infrastructure definition](#select-a-different-infrastructure-when-propagating-environment-from-a-previous-stage).

{% hint style="info" %}
**NOTE**

You can also propagate services between stages. For more information, go to [Propagate CD services](/continuous-delivery/use-continuous-delivery/cd-building-blocks/services/propagate-and-override-cd-services.md).
{% endhint %}

#### Important notes <a href="#important-notes" id="important-notes"></a>

* Propagation is only supported for Deploy stages. Custom stages do not have environments.
* You cannot propagate environments between different deployment types. For example, you cannot propagate a Kubernetes environment between a Kubernetes deployment stage and a Shell Script deployment stage.
* Environment propagation is not supported when using multiple environments in a single stage (multi environment deployments).
* Environment propagation is progressive. You can only propagate environments from stage to stage in a forward direction in your pipeline. For example, Stage 2 cannot propagate an environment from a subsequent Stage 3.
* In a pipeline's **Advanced Options**, in **Stage Execution Settings**, you can set up selective stage executions. This allows you to select which stages to deploy at runtime.
  * If you select a stage that uses a propagated environment (a child environment), that stage will not work. This is because the parent environment's settings must be resolved as part of the deployment.
* When propagation is set up between a parent stage and child stage, moving the parent or child stage out of sequence resets any propagated settings to their defaults. If you do this, you are prompted to confirm. If you confirm, the stages are reset to their defaults.
* You cannot propagate environment from a stage which also propagates environment from another stage.

  ![picture 0](/files/TkQ5gxZF9i3RYaF9geP0)

#### Propagate an environment <a href="#propagate-an-environment" id="propagate-an-environment"></a>

1. Open a pipeline that contains at least one Deploy stage.
2. Add a subsequent Deploy stage.
3. In **Service**, select a service for the stage, and then select **Continue**.
4. In **Environment**, select **Propagate Environment From**.
5. In **Propagate Environment From**, select the environment of a previous stage.

   The environment and infrastructure definition from the previous stage is now configured in this stage.

   <figure><img src="/files/FuM1AB7v7ztoAc3s0aHh" alt=""><figcaption><p>Click to view full size image</p></figcaption></figure>

#### Select a different infrastructure when propagating environment from a previous stage <a href="#select-a-different-infrastructure-when-propagating-environment-from-a-previous-stage" id="select-a-different-infrastructure-when-propagating-environment-from-a-previous-stage"></a>

When you [propagate an environment](#propagate-an-environment) from a previous stage, you have the option to select a different infrastructure definition.

1. Select a stage for which you want to propagate the environment and infrastructure. Make sure that the selected stage has at least one previous Deploy stage.
2. In the **Environment** tab, select **Propagate Environment From** and select the environment of a previous stage.
3. Select **Deploy to Different Infrastructure** and select an infrastructure. This option allows you to select a different infrastructure definition.
4. Select **+ New Infrastructure** to [create a new infrastructure definition](#add-infrastructure-definitions) for use in your stage.

   <figure><img src="/files/4IUJmlHeGxLOHTV0NqDX" alt=""><figcaption><p>Click to view full size image</p></figcaption></figure>

{% hint style="info" %}
**LIMITATION**

* Harness doesn't support nested propagation. For example, if Stage 2 is propagated from Stage 1, you cannot propagate Stage 3 from Stage 2.
* This feature is not supported when deploying to multiple environments or infrastructures.
  {% endhint %}

Here's a sample YAML snipped when a different infrastructure definition is propagated:

```yaml
environment:
  useFromStage:
    stage: s1
  infrastructureDefinitions:
    - identifier: infra_1
      inputs:
        identifier: infra_1
        type: KubernetesDirect
        spec:
          connectorRef: <+input>
```

### Define GitOps clusters <a href="#define-gitops-clusters" id="define-gitops-clusters"></a>

When you use Harness GitOps you can add GitOps clusters to an environment.

To learn more about Harness GitOps, go to [Harness GitOps basics](/continuous-delivery/use-gitops/get-started/harness-git-ops-basics.md).

Next, when you create a pipeline, you can select the environment and the GitOps cluster(s) to use.

![](/files/eCaqwemAVtspNfGGtwxz)

GitOps clusters are used in a PR pipeline. A PR pipeline creates and merges a Git PR on the `config.json` for a destination cluster as part of an ApplicationSet. The PR Pipeline runs, merges a change to the config.json, and a GitOps sync on the ApplicationSet is initiated.

GitOps Clusters are not used in standard CD pipelines. They're used when using GitOps only.

### Clone Environments <a href="#clone-environments" id="clone-environments"></a>

You can clone environment across scopes (i.e from one project to another, project to organization, account to project etc.).

Select **More Options**. Select **Clone** ![](/files/Gcw84bZtXMFyo6bHrtbz)

Once you click on **Clone**, you will see the **Clone Environment** setting:

You can change the **Name**, and add tags, or descriptions for this clone environment.

You can modify the destination of your clone environment using the **Organization** and **Project** fields.

The checkbox **Do you want to clone infrastructures?** is checked by default. The infrastructures in the environment will be cloned as inline by default, regardless of the destination being remote or inline environment. Uncheck the checkbox if you do not want to clone all the infrastructures in the environment.

You can choose between **Inline** and **Remote** to set up your environment. Choose **Inline** when you want your environments to be stored in Harness. Choose **Remote** when storing your environment in a Third-party Git repository or Harness Code Repository.

To clone a remote environment to an inline environment, you have to specify the source branch where the remote environment is stored.

![](/files/WbvcqykcwwcGxYRSoH7u)

To clone an inline environment or remote environment to a remote environment, you must specify the target repository, Harness Code Repository, to store the environment in the Harness repository or Third-party Git provider, to store the environment in a third party Git provider, define the Git Connector if Third-party Git provider. Specify the Repository name, the YAML path, and the commit message.

![](/files/3rqGRvXWekf64YJ2cpzs)

{% hint style="info" %}
**NOTE**

When you clone an environment from a different organization or project, the connector referenced in the infrastructure doesn't get cloned and must be explicitly created.
{% endhint %}

### Runtime inputs and expressions in environments <a href="#runtime-inputs-and-expressions-in-environments" id="runtime-inputs-and-expressions-in-environments"></a>

If you use runtime inputs in your environments, you will need to provide values for these when they run pipeline using these environments.

If you use expressions in your environments, Harness must be able to resolve these expressions when users run pipeline using these environments.

Select **Runtime input** for the environment.

![](/files/Y6KQiGHpSqXCOEgsFlvq)

When you run the pipeline, you can select the environment for their runtime inputs.

![](/files/36qVZI568vePkuy1NlCE)

For more information on runtime inputs and expressions, go to [fixed values, runtime inputs, and expressions](/harness-ai/use-harness-platform/variables-and-expressions/runtime-inputs.md).
