Skip to content

Terraform Providers can sometimes be a bit clunky when you are working locally vs what your final pipeline configuration will be. For instance, often an AWS role will be limited to pipeline access and not allowed to be assumed by users for security reasons. Users will have to authenticate with their SSO roles for any actions they perform instead.

While Terraform supports this with the profile = <your-sso-profile> configuration, this means setting specific values in your local development, remembering to change those before committing/pushing to your project, etc.

Now, there is way you can get the best of both worlds, with dynamic "assume_role" and some clever logic!

Overview

This is a short post, but super useful if you are developing Terraform code you want to work in your pipeline without going back and forth and commenting things in/out for your providers.tf config.

As an example for using a role with GitLab CI pipelines, you may want to have that role limited to specifically GitLab OIDC identity and not let your developers actually assume that role. This helps ensure security and no one abusing a potentially pervasive and highly permissive role, so that you can have flexible (and auditable) pipeline IAM access.

The challenge is, since you can't assume the role as a developer, how are you supposed to test locally in Terraform? You could comment out the assume_role block and put in your profile = my-sso-profile for your specific account.

What if we could instead make it dynamic and allow either and override for local development? You totally can!

Configuration

Here's an example of an AWS Provider configuration where we do exactly that.

# variables.tf
variable "region" {
    description = "The AWS region where you are deploying resources."
    type = string
    default = "us-west-2"
}

variable "account_id" {
    description = "The 12 digit AWS account ID where resources should be deployed."
    type = string
    default = ""
}

variable "sso_profile" {
    description = "Optional parameter for running locally with AWS SSO profile."
    type = string
    default = null
}
# providers.tf
provider "aws" {
    region = var.region
    profile = var.sso_profile
    dynamic "assume_role" {
        for_each = var.sso_profile != null ? [] : [1]
        content {
            role_arn = provider::aws::arn_builder("aws", "iam", "", var.account_id, "role/your-terraform-role")
        }
    }
}

This allows you do export your SSO profile when working locally, but still let the default pipeline role when running without that variable defined!

Then all you have to do is export TF_VAR_sso_profile=my-sso-profile, run your terraform commands, and when you commit / push / run your code in pipelines with your role, nothing has to change! Simple!