amazon-web-servicesterraformterragrunt

How To Have Terragrunt Auto Set "AWS_PROFILE" environment variable?


I cannot for the life of me get this to work. I need to have the AWS_PROFILE environment variable set to get terragrunt to run properly. If I run:

export AWS_PROFILE=myprofile; terragrunt plan

That will work, but that's not what I'm after I want to just run:

terragrunt plan

and have that auto choose the correct aws profile I should be using. Here is what I have:

generate "provider" {
  path = "provider.tf"
  if_exists = "overwrite_terragrunt"
  contents = <<EOF
provider "aws" {
  region  = "${local.region}"
  profile = "${trimspace(run_cmd("bash", "${get_parent_terragrunt_dir()}/../../set_profile.sh",local.profile))}"
}
EOF
}
remote_state {
  backend = "s3"
  generate = {
    path      = "backend.tf"
    if_exists = "overwrite"
  }
  config = {
    ...
    ...
    region         = local.region
    profile        = local.profile
    ...
    ...
  }
}

It always throws the error on me:

Error finding AWS credentials (did you set the AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables?): NoCredentialProviders: no valid providers in chain. Deprecated.
        For verbose messaging see aws.Config.CredentialsChainVerboseErrors

The set_profile.sh script is the following:

#!/bin/bash

VALUE=$(echo $1 | sed $'s/\r//')
export AWS_PROFILE=$VALUE
echo "$AWS_PROFILE"

If I echo out my AWS_PROFILE it's still blank. So it's like the run command isn't actually saving the export value to my console.

What am I doing wrong? Has anyone actually successfully been able to dynamically set their AWS_PROFILE with terragrunt?


Solution

  • That's my solution. I have the following structure:

    <project>
        |-- <region1>
        |-- <region2>
        |-- account.hcl
    terragrunt.hcl
    

    In account.hcl

    locals {
      aws_profile_name = "myprofile"
    }
    

    In main terragrunt.hcl

    locals {
      # Automatically load account-level variables
      account_vars = read_terragrunt_config(find_in_parent_folders("account.hcl"))
    
      aws_profile = local.account_vars.locals.aws_profile_name
    }
    
    terraform {
      extra_arguments "aws_profile" {
        commands = [
          "init",
          "apply",
          "refresh",
          "import",
          "plan",
          "taint",
          "untaint"
        ]
    
        env_vars = {
          AWS_PROFILE = "${local.aws_profile}"
        }
      }
    }
    
    remote_state {
      ...
      config = {
        ...
        profile = "${local.aws_profile}"
      }
    }
    
    generate "provider" {
      ...
      contents 
      contents  = <<EOF
    provider "aws" {
      profile = "${local.aws_profile}"
    }
    EOF
    }
    ...