Overview of terraform
Getting Started
Install
$ brew install terraform
Configuration
provider "aws" { access_key = "ACCESS_KEY_HERE" secret_key = "SECRET_KEY_HERE" region = "us-east-1" }
resource "aws_instance" "example" { ami = "ami-2757f631" instance_type = "t2.micro" }
Execution Plan and Apply
$ terraform plan # create real resources $ terraform apply # the terraform.tfstate file maps various resource metadata to actual resource IDs so that Terraform knows what it is managing. # You can inspect the state using terraform show $ terraform show
- https://www.terraform.io/docs/commands/apply.html
- https://www.terraform.io/docs/commands/plan.html
- https://www.terraform.io/docs/commands/show.html
Change Infrastructure
resource "aws_instance" "example" { + ami = "ami-2757f631" - ami = "ami-b374d5a5" instance_type = "t2.micro" }
Destroy Infrastructure
# verify exactly what resources Terraform is managing and will destroy $ terraform plan -destroy # destroy the infrastructure $ terraform destroy
Resource Dependencies
resource "aws_instance" "example" { ami = "ami-b374d5a5" instance_type = "t2.micro" } # This resource type allocates and associates an elastic IP to an EC2 instance. # The only parameter for aws_eip is "instance" which is the EC2 instance to assign the IP to. resource "aws_eip" "ip" { instance = "${aws_instance.example.id}" }
Implicit and Explicit Dependencies
# you can also specify explicit dependencies with the depends_on parameter which is available on any resource. resource "aws_eip" "ip" { instance = "${aws_instance.example.id}" depends_on = ["aws_instance.example"] }
# If you're ever unsure about the dependency chain that Terraform is creating, you can use the terraform graph $ terraform graph
Defining a Provisioner
Provisioners are used to execute scripts on a local or remote machine as part of resource creation or destruction.
resource "aws_instance" "example" { ami = "ami-b374d5a5" instance_type = "t2.micro" provisioner "local-exec" { command = "echo ${aws_instance.example.public_ip} > ip_address.txt" } }
$ cat ip_address.txt 54.192.26.128
Defining Variables
variable "access_key" {} variable "secret_key" {} # If a default value is set, the variable is optional. variable "region" { default = "us-east-1" }
# Using Variables in Configuration provider "aws" { access_key = "${var.access_key}" secret_key = "${var.secret_key}" region = "${var.region}" }
Assigning Variables
# Command-line flags $ terraform plan \ -var 'access_key=foo' \ -var 'secret_key=bar'
access_key = "foo" secret_key = "bar"
$ terraform plan \ -var-file="secret.tfvars" \ -var-file="production.tfvars"
Lists
# implicitly by using brackets [...] variable "cidrs" { default = [] } # explicitly variable "cidrs" { type = "list" }
cidrs = [ "10.0.0.0/16", "10.1.0.0/16" ]
Maps Maps are a way to create variables that are lookup tables.
variable "amis" { # A variable can have a map type assigned explicitly, or it can be implicitly declared as a map by specifying a default value that is a map. type = "map" default = { "us-east-1" = "ami-b374d5a5" "us-west-2" = "ami-4b32be2b" } }
resource "aws_instance" "example" { ami = "${lookup(var.amis, var.region)}" instance_type = "t2.micro" }
$ terraform plan -var 'amis={ us-east-1 = "foo", us-west-2 = "bar" }'
variable "region" {} variable "amis" { type = "map" }
amis = { "us-east-1" = "ami-abc123" "us-west-2" = "ami-def456" }
$ terraform apply -var region=us-west-2 Apply complete! Resources: 0 added, 0 changed, 0 destroyed. Outputs: ami = ami-def456
Defining Outputs
Outputs are a way to tell Terraform what data is important. This data is outputted when apply is called, and can be queried using the terraform output command.
output "ip" { value = "${aws_eip.ip.public_ip}" }
Viewing Outputs
$ terraform apply Apply complete! Resources: 0 added, 0 changed, 0 destroyed. Outputs: ip = 50.17.232.209
$ terraform output ip 50.17.232.209
Modules
provider "aws" { access_key = "AWS ACCESS KEY" secret_key = "AWS SECRET KEY" region = "AWS REGION" } # The module block tells Terraform to create and manage a module. module "consul" { # The source configuration is the only mandatory key for modules. It tells Terraform where the module can be retrieved. source = "github.com/hashicorp/consul/terraform/aws" key_name = "AWS SSH KEY NAME" key_path = "PATH TO ABOVE PRIVATE KEY" region = "us-east-1" servers = "3" }
# Prior to running any command such as plan with a configuration that uses modules, you'll have to get the modules. $ terraform get # The terraform get command is used to download and update modules mentioned in the root module. https://www.terraform.io/docs/commands/get.html
- https://www.terraform.io/docs/modules/index.html
- http://qiita.com/zembutsu/items/1e4424314a0ad98bcc40
Remote Backends - In production environments it is more responsible to run Terraform remotely and store a master Terraform state remotely. - Terraform Enterprise allows teams to easily version, audit, and collaborate on infrastructure changes. - functions as a Terraform backend as well as enabling many other features such as remote apply, run history, state history, state diffing, and more
githubのterraform版みたいな感じ?
# configure the backend in your configuration terraform { backend "consul" { address = "demo.consul.io" path = "getting-started-RANDOMSTRING" lock = false } }
# After configuring a backend, run terraform init to setup Terraform. $ terraform init $ terraform plan # ... No changes. Infrastructure is up-to-date. This means that Terraform did not detect any differences between your configuration and real physical resources that exist. As a result, Terraform doesn't need to do anything. # Terraform is now storing your state remotely in Consul.
Terraform Enterprise
$ export ATLAS_TOKEN=ATLAS_ACCESS_TOKEN
terraform { backend "atlas" { name = "USERNAME/getting-started" } } # Note that the backend name is "atlas" for legacy reasons and will be renamed soon.
$ terraform init
$ git init $ git add example.tf $ git commit -m "init commit" # push your Terraform configuration to Terraform Enterprise $ terraform push
This will automatically trigger a terraform plan, which you can review in the Terraform page. If the plan looks correct, hit “Confirm & Apply” to execute the infrastructure changes.
所感
- consul使ってみたい
- Modules, Terraform Enterprise, Provisioner使ってみたい
- でもこの辺使い出したらもう仕事関係ないんだよなー笑
- Terraform Enterpriseのページがかっこよかった