Customized layering support?

This is because Terraspace detects info like AWS account early on during the build phase, not during run/apply phase. You can use the standard AWS profile instead of the Terraform role_arn. The AWS profile switches earlier, so the same role and AWS account will be used by both terraspace and terraform.

Note, it’s a decent effort for Terraspace to parse for terraform role_arn. Will consider PRs, though. The recommendation is to use ~/.aws currently.

Docs: Using an IAM role in the AWS CLI - AWS Command Line Interface

Steps:

  1. Use aws role_arn in your .aws/config and .aws/credentials instead.
  2. Remove the role_arn in your current code

RE: Custom Layering, Complexity, Sweeping Under the Rug

If you’re going down the route of custom layering and porting things as-is, it won’t get rid of code complexity. You’re trading one set of complexities for another. Instead of a complex hierarchical path structure, there’s complexity with env vars. So:

$ export AWS_PROFILE=shared-iam
$ cd teamA/qa/service-01/us-east-1/demo
$ terragrunt plan

Becomes:

$ TEAM=teamA \
  TS_ENV=qa \
  SERVICE=service-01 \
  AWS_REGION=us-east-1 \
  AWS_PROFILE=profile1 \
  terraspace up demo

It’s actually worse to have to remember all the env vars.

This is the typical course for hierarchical mono-repo setup because they naturally result in more complex systems. There are simply more moving parts. To be clear, this doesn’t necessarily mean micro-repos are better. It depends. Try to find a good balance between the 2 approaches that fit your needs.

You can consider using one env var and using a boot hook to set the rest of them. Note, use version Terraspace v0.6.2. Made some changes:

Terraspace offers a lot of control in that you can tap into a full programming language. Example:

config/boot.rb

app = ENV['APP'] || ''
team, ts_env, service, region, profile = app.split('/').map { |x| x.blank? ? nil : x }

ENV['TEAM']        = team    || 'teamA'
ENV['TS_ENV']      = ts_env  || 'dev'
ENV['SERVICE']     = service || 'service1'
ENV['AWS_REGION']  = region  || 'us-east-1'
ENV['AWS_PROFILE'] = profile || 'dev-profile' # or logic to handle the different profiles

This “sweeps the garbage under the rug” to mask the complexity.

APP=teamB/prod/service2/us-east-2/prod-profile terraspace build demo

Generally

Consider reviewing your current structure to see if there are opportunities to remove unnecessary or little-used parts. Sometimes removing even the littlest thing can dramatically decrease complexity.

Of course, it may not be feasible to refactor because of existing statefiles which would require a major “lift-and-shift” migration. So maybe you’ll just have to use the learnings for future setups. That’s what Terraspace’s defaults encapsulate. It’s not perfect, nothing ever is, but it should hopefully account for 80-90% uses.