> 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/infrastructure-as-code-management/platform/iacm-connectors-variables/aws-connector-auth/multiple-aws-oidc-accounts.md).

# Multiple AWS OIDC accounts

Configure environment variables and Terraform provider aliases to authenticate multiple AWS accounts in one IaCM workspace.

{% hint style="info" %}
This feature is in Beta[^1] and requires enablement. [View all early access features.](/release-notes/features.md)

{% @harness-feature-flag-access/request-feature-flag-access module="infrastructure-as-code-management" pagePath="infrastructure-as-code-management/platform/iacm-connectors-variables/aws-connector-auth/multiple-aws-oidc-accounts" featureFlags="%5B%7B%22name%22%3A%22Multiple%20AWS%20OIDC%20Accounts%22%2C%22key%22%3A%22IACM\_MULTI\_CLOUD\_OIDC\_IDENTITIES%22%2C%22status%22%3A%22BETA%22%2C%22description%22%3A%22Enables%20an%20IaCM%20workspace%20to%20hold%20multiple%20AWS%20identities%20at%20once%2C%20one%20per%20AWS%20account%2C%20configured%20through%20environment%20variables%20instead%20of%20a%20connector.%22%7D%5D" %}
{% endhint %}

By default an IaCM workspace uses one AWS connector. You can configure a workspace to authenticate to more than one AWS account in the same run instead, using environment variables in place of the connector. Each account gets its own OIDC identity, and your Terraform or OpenTofu provider blocks pick which one to use per resource. Use this when resources across accounts depend on each other and need to be planned together. If your accounts do not reference each other, one workspace per account is simpler.

## Before you begin

* Set up an AWS OIDC connector at least once. Go to [AWS connector authentication](/infrastructure-as-code-management/platform/iacm-connectors-variables/aws-connector-auth.md) for the IAM OIDC identity provider and role setup. Nothing about that setup changes here.
* Have the IAM role ARN ready for every AWS account the workspace provisions into. Each role's AWS account needs an OIDC identity provider that trusts your Harness account's issuer, with a trust policy matching the audience and subject that Harness mints.
* You need permission to create variable sets and edit workspace variables. Go to [Workspace RBAC](/infrastructure-as-code-management/platform/workspaces/workspace-rbac.md) to check your IaCM permissions.

***

## Environment variables

`PLUGIN_MULTIPLE_AWS_OIDC_CONNECTOR` controls the mode:

* Not set, or `false`: the workspace uses its AWS connector as usual. Identity variables are ignored.
* `true`: IaCM does not use the workspace AWS connector for authentication, regardless of connector type (simple, IRSA, or OIDC). Identities come only from the variables below. If no identity is enabled, the workspace fails at prepare instead of falling back to the connector.

For each account, choose a tag, such as `acc1` or `acc2`, and set the following variables. The tag is case-preserved: it becomes both the map key in the injected Terraform variable and part of the generated AWS config filename, so use the same casing everywhere you reference it.

| **Variable**                               | **Description**                                                                                                     |
| ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------- |
| `PLUGIN_MULTIPLE_AWS_OIDC_CONNECTOR`       | Switches the workspace from its AWS connector to per-account identity variables.                                    |
| `HARNESS_IDENTITY_AWS_PROVIDER_AUTH_<tag>` | Enables the identity named `<tag>`. Set to the literal string `true`.                                               |
| `HARNESS_IDENTITY_AWS_ROLE_ARN_<tag>`      | The IAM role ARN this identity assumes. Required whenever `PROVIDER_AUTH_<tag>` is `true`.                          |
| `HARNESS_IDENTITY_AWS_REGION_<tag>`        | Optional. AWS STS endpoint region used to mint the token for this identity. Does not set the AWS provider's region. |

* `HARNESS_IDENTITY_AWS_PROVIDER_AUTH_<tag>`: `true`. Enables the identity named `<tag>`. Only the literal string `true` enables it.
* `HARNESS_IDENTITY_AWS_ROLE_ARN_<tag>`: the IAM role ARN for that account. Required whenever `PROVIDER_AUTH_<tag>` is `true`. This role is never inherited from the workspace connector.
* `HARNESS_IDENTITY_AWS_REGION_<tag>`: optional. Selects the AWS STS endpoint used to mint the token for this identity (the global `sts.amazonaws.com` endpoint by default, or `sts.<region>.amazonaws.com` when set). It does not set the AWS provider's region and does not appear in the injected Terraform variable. Set the provider region in your HCL.

For example, an `oidc_acc1` variable set:

```
HARNESS_IDENTITY_AWS_PROVIDER_AUTH_acc1 = true
HARNESS_IDENTITY_AWS_ROLE_ARN_acc1      = arn:aws:iam::123456789012:role/iacm-oidc-acc1
```

And an `oidc_acc2` variable set:

```
HARNESS_IDENTITY_AWS_PROVIDER_AUTH_acc2 = true
HARNESS_IDENTITY_AWS_ROLE_ARN_acc2      = arn:aws:iam::210987654321:role/iacm-oidc-acc2
```

Create a [variable set](/infrastructure-as-code-management/platform/iacm-connectors-variables/variable-sets.md) for each account instead of adding the variables directly to the workspace. Variable sets let you reuse an account configuration across multiple workspaces without duplicating the variables. Import the sets you need and set `PLUGIN_MULTIPLE_AWS_OIDC_CONNECTOR` directly on the workspace.

All of these are strings, not booleans. Enter `true` in lowercase.

Set these as environment variables, not Terraform/OpenTofu variables. A same-named Terraform variable does not reach the plugin.

***

## Configure the provider blocks

Harness injects the identities into your run as a Terraform variable, `harness_cloud_identities`, keyed by tag. Harness declares this variable for you at runtime, so you do not add a `variable` block for it. Reference it directly.

One `provider "aws"` block per tag, pointed at that tag's config files:

```hcl
provider "aws" {
  alias               = "acc1"
  region              = "us-east-1"
  shared_config_files = var.harness_cloud_identities["acc1"].shared_config_files
}

provider "aws" {
  alias               = "acc2"
  region              = "us-east-1"
  shared_config_files = var.harness_cloud_identities["acc2"].shared_config_files
}
```

Set `region` explicitly in each provider block. `harness_cloud_identities` never carries a region.

The map key has to match the tag exactly, case included. Configure a provider block for every tag you use. There is no fallback credential in this mode.

Assign resources to the provider they need:

```hcl
resource "aws_s3_bucket" "acc1" {
  provider = aws.acc1
  bucket   = "app-data-acc1"
}

resource "aws_s3_bucket" "acc2" {
  provider = aws.acc2
  bucket   = "app-data-acc2"
}
```

For modules, aliased providers are not inherited automatically. Pass them explicitly:

```hcl
module "acc2_network" {
  source    = "./modules/network"
  providers = {
    aws = aws.acc2
  }
}
```

One thing to plan around: `provider` has to be a static reference. You cannot do `aws[each.key]` or point it at a variable, since provider configuration resolves before variables do. For many similarly-shaped accounts, consider one workspace per account instead.

***

## Worked example

**Harness, on the workspace**

```
Import variable sets   oidc_acc1, oidc_acc2
Workspace variable     PLUGIN_MULTIPLE_AWS_OIDC_CONNECTOR = true
```

The `oidc_acc1` and `oidc_acc2` variable sets each carry their `PROVIDER_AUTH` and `ROLE_ARN` pair. Priority only decides which set wins if two sets define the same key; here the tags differ, so both apply:

![Workspace variable sets and the resulting environment variables for the acc1 and acc2 AWS identities](https://3575326923-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Ffhx6XzjvtJmfv5gPWZ5m%2Fuploads%2Fgit-blob-989572f80df2e05195b1bf47fde83da83b52edc3%2Fmultiple-aws-oidc-variable-sets.png?alt=media)

**Terraform or OpenTofu**

```hcl
provider "aws" {
  alias               = "acc1"
  region              = "us-east-1"
  shared_config_files = var.harness_cloud_identities["acc1"].shared_config_files
}

provider "aws" {
  alias               = "acc2"
  region              = "us-east-1"
  shared_config_files = var.harness_cloud_identities["acc2"].shared_config_files
}

resource "aws_s3_bucket" "acc1" {
  provider = aws.acc1
  bucket   = "app-data-acc1"
}

resource "aws_s3_bucket" "acc2" {
  provider = aws.acc2
  bucket   = "app-data-acc2"
}
```

**Verify:** Check the init logs for a line similar to `PLUGIN_CLOUD_IDENTITIES: parsed 2 identities`, followed by one `[AUDIT] AWS cloud identity validated` line per tag.

***

## Next steps

* Go to [AWS connector authentication](/infrastructure-as-code-management/platform/iacm-connectors-variables/aws-connector-auth.md) for single-account AWS authentication methods, including OIDC, IRSA, and node role.
* Go to [Variable sets](/infrastructure-as-code-management/platform/iacm-connectors-variables/variable-sets.md) to create, attach, and prioritize the per-account variable sets this configuration relies on.
* Go to [Connectors and variable sources](/infrastructure-as-code-management/platform/iacm-connectors-variables/connectors-variables.md#multiple-connectors) to review how Harness resolves a workspace's connectors and variables.

{% @harness-feedback/feedback %}

[^1]: Beta features are feature-complete but still being validated. Available on request.
