0
votes

What is the best way to setup terraform for multiple environments (dev, stage, prod) in AWS with just a single account. My client has provided only a single account for us to use. Most write ups about using terraform always start off with using multiple accounts which I don't have. I plan on using S3 backend storage because there will be a couple of us supporting the infrastructure.

2
Don't use workspaces for multiple environment deployments unless you are only deploy pretty static infrastructure. Because it is not easy to branch your terraform code. Say you are working on the next release updating terraform. But you find a bug in production that needs an update. There is no easy way to branch the production environment to patch and then merge the patch back into development. The solution is to use a version control system like git for you terraform code.WaltDe
Of course you should version control your infrastructure as code so that you can track the changes and rollback in case of faults. If you adopt version control solutions, bugfixing your infrastructure will be as easy as bugfixing any application. In the scenario proposed by @WaltDe, you could branch, fix the problem, test it in staging/dev and once you are satisfied you can merge it into master and apply to production.jackops

2 Answers

-1
votes

This will work for the most use cases

Option 1: use regions

This has the benefit of keeping things separated in the console and api calls. You will need to handle a few global named services like IAM and S3 but see option 2 on a solution. Also, make sure that the regions all have the services you need to use.

For example:

  • us-east-1: prod
  • us-east-2: qa
  • us-west-2: dev

In each region create a S3 bucket to store your state files. Something like tfstate-01234567890-us-east-1, tfstate-01234567890-us-east-2, tfstate-01234567890-us-west-1 will ensure that you don't have conflicts.

Option 2: use an environment tag

Even if you are doing option 1 I still recommend implementing this as well. It will let you do things like deploy multiple development environments.

For each resource append the environment to the name and add the environment to the tags.

Say you create a module

variable environment {
  type = string
}
resource aws_lambda_function image_handler {
  function_name = "cool-function-${var.environment}"
  tags = {
    environment: var.environment
  }
... 

Then you would

module dev {
  source = "../path/to/above/module"
  environment = "prod"
}
-1
votes

You should not split the environments using different regions. Regions are there to improve the resilience of the system in case e.g., a temporary breakdown occurs on a specific data center.

Also having custom environment variables will not help you because you will end up having code duplication.

Your north star should be having an exact replica of the two environments and avoid code duplication. Terraform helps you on this because it has the concept of workspaces. In this way you will be using the same configuration and you can change environment with a single command like terraform workspace select staging/dev/production