Terraform: Deploying to Multiple AWS Accounts Using Terraform

Created on 27 Feb 2017  ยท  6Comments  ยท  Source: hashicorp/terraform

Hi,

We are trying to deploy to multiple AWS accounts using Terraform using multiple pre-configured profiles and then calling these profiles in the "provider" section but this is not working correctly. Is this indeed an issue with Terraform?

Terraform Version

v0.8.7

Affected Resource(s)

Please list the resources as a list, for example:

  • N/A (because this is an issue with "profiles" instead of a resource).

Terraform Configuration Files

provider "aws" { 
    region = "us-west-2"
    profile = "test"
    shared_credentials_file = "~/.aws/credentials"
}

Debug Output

See 'Actual Behavior'

Expected Behavior

Terraform should deploy to the test account.

Actual Behavior

Terraform deploys to the prod account.

Steps to Reproduce

  1. Configure the AWS profile/s:

config file location: "~/.aws/config"

[profile test]
role_arn = arn:aws:iam:::role/
source_profile = prod
output = json
region = us-west-2

[profile prod]
output = json
region = us-west-2

  1. Configure AWS credentials:

credentials file location: "~/.aws/credentials"

[prod]
aws_access_key_id =
aws_secret_access_key =

  1. Run Terraform
    terraform apply

Most helpful comment

I recently did with with terraform latest. Here's what it looks like:

provider "aws" {
alias = "productmanagement"
access_key = "${var.productmanagement_access_key}"
secret_key = "${var.productmanagement_secret_key}"
region = "${var.region}"
}
provider "aws" {
alias = "prod"
access_key = "${var.prod_access_key}"
secret_key = "${var.prod_secret_key}"
region = "${var.region}"
}
Then using the providers...
resource "aws_lambda_permission" "apigw_lambda" {
provider = "aws.prod"
...
}
or
resource "aws_lambda_function" "snscminstanceprocessor" {
provider = "aws.productmanagement"
...
}

I didn't try profile\shared_credentials_file but the above didn't work right until I included the alias and then specified in each resource the provider to use for that resource. I could tell when I forgot to include the alias in the resource because the resource always ended up being created in the wrong account.

Not sure if this will help but hopefully it will!

All 6 comments

It appears that Terraform does not accept/understand AWS profiles and only accepts AWS keys. Is this correct? I say this because when specifying a profile that has a key associated with it, Terraform is successfully able to plan and apply otherwise it throws this error:

```
Error refreshing state: 1 error(s) occurred:

Once again, here's what the provider block looks like:

provider "aws" {
region = "${var.region}"
profile = "${var.aws_profile}"
shared_credentials_file = "/Users/user/.aws/credentials"
}

Following up on this issue.

I recently did with with terraform latest. Here's what it looks like:

provider "aws" {
alias = "productmanagement"
access_key = "${var.productmanagement_access_key}"
secret_key = "${var.productmanagement_secret_key}"
region = "${var.region}"
}
provider "aws" {
alias = "prod"
access_key = "${var.prod_access_key}"
secret_key = "${var.prod_secret_key}"
region = "${var.region}"
}
Then using the providers...
resource "aws_lambda_permission" "apigw_lambda" {
provider = "aws.prod"
...
}
or
resource "aws_lambda_function" "snscminstanceprocessor" {
provider = "aws.productmanagement"
...
}

I didn't try profile\shared_credentials_file but the above didn't work right until I included the alias and then specified in each resource the provider to use for that resource. I could tell when I forgot to include the alias in the resource because the resource always ended up being created in the wrong account.

Not sure if this will help but hopefully it will!

thanks @KyronSr. This was a configuration issue and so I figured this one out. Here's what the working config looks like:

provider "aws"
region = "${var.region}"
profile = "${var.aws-profile}"
shared_credentials_file = "${pathexpand("~/.aws/credentials")}"
assume_role {
role_arn = "${var.profile-arn}"
}}

variable "aws-profile" {
description =
"This profile uses an ssh key-pair stored on the client aws config file."
default = "profile-name"
}

variable "profile-arns" {
description = "AWS profile ARNs."
default = {
us-west-2-test = "arn:aws:iam::acct-id:role/role-name"
us-west-2-live = "arn:aws:iam::acct-id:role/role-name"
}}

Note: the default profile is setup for cross account access which is why this config works for multiple accounts.

I did have an issue with Terraform parsing the "~" in the "shared_credentials_file" path but using "pathexpand" in the code above seems to work.

Thanks, @KyronSr. I was experiencing the same, followed your advice with a bit of modification, that I feel is more secure but is based on your approach, Turns out all I have to do is include following lines at the start of my terraform configuration

provider "aws" {
alias = "productmanagement"
profile = "your-aws-profile-name-for-productmanagement-account"
}
provider "aws" {
alias = "prod"
profile = "your-aws-profile-name-for-prod-account"
}

and reference profiles in resources intended to be deployed in each account, in the following fashion as mentioned by @KyronSr

Then using the providers...
resource "aws_lambda_permission" "apigw_lambda" {
provider = "aws.prod"
...
}
resource "aws_lambda_function" "snscminstanceprocessor" {
provider = "aws.productmanagement"
...
}

The only difference I can see in my code and @KyronSr code is I am not exposing my aws credentials via variables files

Thanks

I'm going to lock this issue because it has been closed for _30 days_ โณ. This helps our maintainers find and focus on the active issues.

If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

zeninfinity picture zeninfinity  ยท  3Comments

sprokopiak picture sprokopiak  ยท  3Comments

rkulagowski picture rkulagowski  ยท  3Comments

carl-youngblood picture carl-youngblood  ยท  3Comments

franklinwise picture franklinwise  ยท  3Comments