Supporting Multiple Environments - Best Practices?

463 views
Skip to first unread message

Ryan Bowlby

unread,
Jun 1, 2015, 7:21:10 PM6/1/15
to terrafo...@googlegroups.com
I have nearly identical infrastructure in development, test, staging, and production environments. I'm assuming it's a common configuration pattern to have to support multiple, nearly identical, environments. Often the differences are rather small, e.g. host count, AWS account, hosted zone id, etc.

As it is currently, I've created a terraform configuration directory per-env, but a good bit of duplicity will ensue if I continue down this path. Joel in IRC recommended abstracting the commonalities to a module. Is that a normal approach? Is that the long term approach for sanely configuring multiple environments? Does anyone have an example set of configuration that is used for multiple environments?

Thanks!

Dave Dash

unread,
Jun 1, 2015, 7:32:27 PM6/1/15
to Ryan Bowlby, terrafo...@googlegroups.com
I have a small installation where I do something like this.

I have variables found counts for everything.  I can turn off many things by setting something to “0”

The one are where this fails is with ELB - but maybe I need to put a count on that.  (i.e. 0 instances in an LB will fail, but maybe if I specify 0 load balancers it’ll be fine).

I’ve also found out if you are trying new things it’s hard to just edit one module - so I’ve been copying modules (literally cp module1/ module2) and then make my backwards incompatible changes to module2.

It’s served me well, but it’s not as clean as I’d like.

-d


--
You received this message because you are subscribed to the Google Groups "Terraform" group.
To unsubscribe from this group and stop receiving emails from it, send an email to terraform-too...@googlegroups.com.
To post to this group, send email to terrafo...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/terraform-tool/166ef031-10c6-42c0-8529-9c4c513b69ec%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

ja...@fpcomplete.com

unread,
Jun 2, 2015, 12:01:20 AM6/2/15
to terrafo...@googlegroups.com


On Monday, June 1, 2015 at 7:21:10 PM UTC-4, Ryan Bowlby wrote:
I have nearly identical infrastructure in development, test, staging, and production environments. I'm assuming it's a common configuration pattern to have to support multiple, nearly identical, environments. Often the differences are rather small, e.g. host count, AWS account, hosted zone id, etc.

As it is currently, I've created a terraform configuration directory per-env, but a good bit of duplicity will ensue if I continue down this path. Joel in IRC recommended abstracting the commonalities to a module. Is that a normal approach? Is that the long term approach for sanely configuring multiple environments? Does anyone have an example set of configuration that is used for multiple environments?

It may take a little while to get used to, and it is often slower to develop with modules, it has been worth the trouble.. so far in my experience. It is nice to take a working pattern and put it into a module. They can also be stacked.. so I have a module to create Auto-Scaling Groups with subnets and security groups, and I have other modules which use that ASG module, and then yet other modules or terraform environments which use those. It makes sense and is not difficult to navigate, though it was not easy to use modules at first.

There are still pain points in practice, particularly for production environments which you might not want to change in the way TF would like to.

Either way.. less code is likely better, but not always. Good luck.

Ryan Bowlby

unread,
Jun 2, 2015, 4:55:57 PM6/2/15
to terrafo...@googlegroups.com
What I've ended up with so far is a module per internal service. Each module makes no assumptions as to region, aws provider, environment, etc. A directory per environment that makes use of the modules.

~/repos/terraform (master●●)$ tree                                                                                       
.
├── dev
│   ├── main.tf
│   ├── provider.tf
│   ├── terraform.tfstate
│   ├── terraform.tfstate.backup
│   ├── terraform.tfvars -> ../terraform.tfvars
│   └── variables.tf -> ../variables.tf
├── int
│   ├── main.tf
│   ├── provider.tf
│   ├── terraform.tfvars -> ../terraform.tfvars
│   └── variables.tf -> ../variables.tf
├── modules
│   └── upload
│       ├── main.tf
│       └── variables.tf
├── terraform.tfvars
├── user_data.txt
└── variables.tf

4 directories, 15 files

The duplication has been appropriately abstracted out. There's been a few places where certain DSL limitations have imposed barriers to legibility or approach, but so far it's working.

~/repos/terraform (master●●)$ cat dev/main.tf
                                                                           
// variables that vary by env are kept local to env dir
variable "region"     {
  description = "AWS region to host your network"
  default = "us-east-1"
}

variable "domain"     {
  default = "sub.domain.tld"
}

module "upload" {
    source = "../modules/upload"
    region = "${var.region}"
    instance_type = "m3.medium"
    key_name = "${lookup(var.ec2_keys, var.region)}"
    zone_id = "${lookup(var.hosted_zone_ids, var.domain)}"
    ami = "${lookup(var.amis, var.region)}"
    environment = "dev"
    domain = "${var.domain}"
    number_of_instances = "3"
}

This seems like a sane approach. How does this compare to others? What I like about these per env directories is separate state files. So a disaster in a non-production environment isn't as likely to impact production.

Thoughts?

Luke Amdor

unread,
Jun 3, 2015, 9:01:47 AM6/3/15
to terrafo...@googlegroups.com
Our setup is pretty close to this. However, we keep the modules in a separate repository. We also have some ruby scripts around updating module versions and updating skeleton files from a specific revision. Our skeleton files include the main.tf, and we only change the main_override.tf.json file per environment.

Ryan Bowlby

unread,
Jun 3, 2015, 9:56:34 PM6/3/15
to terrafo...@googlegroups.com
Interesting, can you give an example of this skeleton approach? Do you have a per env dir and state file too?
Reply all
Reply to author
Forward
0 new messages