1
votes

We are using Terraform to codify all of our infrastructure on AWS. We're using Gitlab for SCM and Gitlab-Runner for CI/CD. We've also started using Atlantis so that we can run all of our Terraform automatically in pull requests.

The Terraform provider we have configured in code looks something like this:

provider "aws" {
  region = "us-east-1"

  assume_role {
    role_arn     = "arn:aws:iam::123456789012:role/atlantis"
    session_name = "terraform"
  }
}

The Gitlab-Runner instance on which Atlantis runs has permissions to assume the "atlantis" role that is referenced in the assume_role block. And that all works great.

However, there are times when I still need to run Terraform manually from the command line. The trouble with this is that when I do so, my account (which is configured as a federated/SAML login) isn't able to assume roles. It does have access to do everything relating to creating and destroying resources, though.

This means that I need to temporarily delete the assume_role block above on my local machine, and then run my Terraform commands. This isn't the end of the world, but it is a little bit annoying. What I want to do is something like: create a second "aws" provider - one which doesn't try to assume another role - like this:

provider "aws" {
  region = "us-east-1"
  alias  = "local-cli"
}

And then I'd call something like terraform plan --provider=local-cli. But sadly there is no such --provider option; I just made that up now. According to the Terraform docs, it looks like I can configure a second provider on a per-resource basis, but really what I'm trying to do is to run Terraform with a second provider on a per-session basis. Are there any solutions for this?

1
Are you sure you cant assume roles at the cli? Is that a IAM issue. I am using federated logins and assuming roles, i'm using saml2aws github.com/Versent/saml2aws to do thisJames Woolfenden

1 Answers

1
votes

This is what I do. I have created a small wrapper in bash which generates the terraform code that changes and generates provider.tf file for you:

cat << EOF > ./provider.tf
terraform {
  backend "s3" {
    bucket = "${TF_VAR_state_bucket}"
    dynamodb_table = "${DYNAMODB_STATE_TABLE}"
    key    = "terraform/$STATE_PATH/terraform.tfstate"
    region = "$REGION"
    encrypt = "true"
  }
}
provider "aws" {
  region  = "$REGION"
  version = "1.51.0"
}
provider "archive" { version = "1.1.0" }
provider "external" { version = "1.0.0" }
provider "local" { version = "1.1.0" }
provider "null" { version = "1.0.0" }
provider "random" { version = "2.0.0" }
provider "template" { version = "1.0.0" }
provider "tls" { version = "1.2.0" }
EOF

This way the provider and setup can change completely across environments.