Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Terraform: How to make sure I run terraform on the expected AWS account

Suppose I want to launch an EC2 instance in my dev account but it is possible that I accidentally run the wrong command and create a temporary credential of prod account instead of dev account, then when I Terraform apply, I will launch the EC2 at prod account?

How can I avoid this from happening? Can I create a text file with dev account id in this folder, then have Terraform compare the account id of my temporary credential with the account id in this file before launching EC2, maybe in null_resource? I cannot figure out how to implement that.

like image 490
user389955 Avatar asked Jun 23 '18 00:06

user389955


People also ask

How does Terraform know which AWS account to use?

The provider alias allows Terraform to differentiate the two AWS providers. To allow users in a different AWS account to assume a role, you must define an AssumeRole policy for that account. This configuration uses the aws_caller_identity data source to access the source account's ID.

How do I authenticate Terraform in AWS?

Note that the usual and recommended way to authenticate to AWS when using Terraform is via the AWS CLI, rather than any of the provider options listed above. To do this, first, install the AWS CLI, then type aws configure . You can then enter your access key ID, secret access key, and default region.


2 Answers

The AWS provider allows you to specify either a list of allowed_account_ids or a list of forbidden_account_ids that you could define to prevent that from happening if necessary.

So you might have a folder structure that looks a little like this:

$ tree -a
.
├── dev
│   ├── bar-app
│   │   ├── dev-eu-west-1.tf -> ../../providers/dev-eu-west-1.tf
│   │   └── main.tf
│   ├── foo-app
│   │   ├── dev-eu-west-1.tf -> ../../providers/dev-eu-west-1.tf
│   │   └── main.tf
│   └── vpc
│       ├── dev-eu-west-1.tf -> ../../providers/dev-eu-west-1.tf
│       └── main.tf
├── prod
│   ├── bar-app
│   │   ├── main.tf
│   │   └── prod-eu-west-1.tf -> ../../providers/prod-eu-west-1.tf
│   ├── foo-app
│   │   ├── main.tf
│   │   └── prod-eu-west-1.tf -> ../../providers/prod-eu-west-1.tf
│   └── vpc
│       ├── main.tf
│       └── prod-eu-west-1.tf -> ../../providers/prod-eu-west-1.tf
├── providers
│   ├── dev-eu-west-1.tf
│   ├── prod-eu-west-1.tf
│   └── test-eu-west-1.tf
└── test
    ├── bar-app
    │   ├── main.tf
    │   └── test-eu-west-1.tf -> ../../providers/test-eu-west-1.tf
    ├── foo-app
    │   ├── main.tf
    │   └── test-eu-west-1.tf -> ../../providers/test-eu-west-1.tf
    └── vpc
        ├── main.tf
        └── test-eu-west-1.tf -> ../../providers/test-eu-west-1.tf

Where your providers/dev-eu-west-1.tf file looks like:

provider "aws" {
  region              = "eu-west-1"
  allowed_account_ids = [
    "1234567890",
  ]
}

And your providers/test-eu-west-1.tf file looks like:

provider "aws" {
  region              = "eu-west-1"
  allowed_account_ids = [
    "5678901234",
  ]
}

This would mean that you could only run Terraform against dev/foo-app when you are using credentials belonging to the 1234567890 account and could only run Terraform against dev/foo-app when you are using credentials belonging to the 5678901234 account.

like image 196
ydaetskcoR Avatar answered Oct 06 '22 23:10

ydaetskcoR


Store your terraform state in an S3 bucket for that account. Make sure the buckets are named uniquely (they have to be unique to a region anyway). If you run it against the wrong account, it will error out because the bucket cannot be found.

like image 23
myron-semack Avatar answered Oct 07 '22 00:10

myron-semack