hashicorp / terraform

Terraform enables you to safely and predictably create, change, and improve infrastructure. It is a source-available tool that codifies APIs into declarative configuration files that can be shared amongst team members, treated as code, edited, reviewed, and versioned.
https://www.terraform.io/
Other
42.59k stars 9.54k forks source link

Using the same template for creating multiple environments #208

Closed tusharm closed 8 years ago

tusharm commented 10 years ago

Hello,

I would like to be able to create a template once and use it to spin up multiple environments. As an example, the "dev" environment may look like {1 load balancer, 1 web server, 1 database} while the "test" environment may look like {1 load balancer, 4 web servers, 1 database}. Of course, the "roles" (web server, database etc) will be passed as user data.

The difference in the instance count between these environments can be supplied as an argument, rather than hardcoding in the template itself. This would allow me to create an "environment definition" that follows the "create once, deploy multiple times" principle.

I don't think this is possible now; maybe https://github.com/hashicorp/terraform/issues/133 will help in getting here. Is this too far fetched? Do you think this can be a useful feature?

Extrapolating on this, how about using the same template for DEV{1 web server, 1 database} and QA{1 load balancer, 2 web servers, 1 database}?

include commented 10 years ago

+1 on this feature request. I have two aws accounts with 3+ environments on each. I would love to have both aws accounts equal and I really think Terraform is the way to go.

smithamax commented 10 years ago

:+1: yeah would love a way to run in the context of an environment, you can kind of do this now with variables, but not that easily.

delitescere commented 10 years ago

:+1:

mitchellh commented 10 years ago

This will come in Terraform 0.4, most likely. We have some ideas about how this will work.

emicklei commented 9 years ago

Can you share some of these ideas ? We are evaluating terraform for managing our internal cloud platform and are discussing this issue as well.

knuckolls commented 9 years ago

You can create an "environment" module with input variables for the things that you want to differ between environments. Due to the fact that you can pull in a module as a git hash or tag, you can have each environment refer to a different point in the git history with differing sets of module inputs per environment.

emicklei commented 9 years ago

Interesting idea to use modules for encapsulation, thanx.

With our limited experience with terraform, we came up with this:

variable "vm_memory" {
    description = "how many gigs do you want"
    default = {
        "D"  = "1G"
        "T"  = "1G"
        "A"  = "4G"
        "X"  = "5G"
        "P"  = "5G"
    }
}

resource "nemesis_vm" "eddy-vm-1" {
    memory = "${lookup(var.vm_memory, var.DTAXP)}"
}

and

terraform apply -var 'DTAXP=T'
mpareja commented 9 years ago

We are experimenting with having global test, uat and prod modules which output the common variables. Our services then have test, uat and prod modules which reference the global modules and forward the variables. It kinda stinks.

module "settings" {
    source = "github.com/org/repo/uat
}

module "world" {
    source = "github.com/org/repo/world"
    vpc_id = "${module.settings.vpc_id}"
}

Notice some settings are slurped in the uat module in our Terraform Github repository. We then reference those in the inputs to the modules/resources we want in an environment. That might be a high-level wrapper module around everything or some specific resources.

/cc @emicklei

c4milo commented 9 years ago

Why this cannot be implemented using modules as well as different directories per environment for the "main.tf" of each one?

ramonskie commented 9 years ago

any update on this?

dansteen commented 9 years ago

I am actually doing this right now. I have a module for each application, which includes (we are using amazon) a EBS, launch_config, autoscale_groups, RDS, Elasticache, S3, SNS, and other components. Then, for each environment, I use that module, and pass in variables for things that need to change (like subnets, number of boxes, etc. It works really nicely, though, I'd love to be able to pass in a VPC object, and then use the components of that in my module. But for now, I pass in the parts I use individually.

lukehutton commented 9 years ago

+1 for reuse

phinze commented 8 years ago

Terraform has a story for reuse as described by the original author here - it's based around modules. Check out the docs for more info!

Our Atlas docs also have a more concrete example of managing multiple envs with modules, whose structure is valid with or without Atlas.

ghost commented 4 years ago

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.

If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.