Terraform notes
Terraform home page
Terraform Documentation
Terraform best pratices
Terraform is a tool for building, changing, and versioning infrastructure safely and efficiently.
Infrastructure as Code
Infrastructure is described using a high-level configuration syntax. This allows a blueprint of your datacenter to be versioned and treated as you would any other code. Additionally, infrastructure can be shared and re-used.
Terraform allows to write code that is specific to each provider, taking advantage of that provicer's unique functionality, but to use the same language and toolset.
Initial release: 2014.
Other provisioning tools:
- Chef
- Puppet
- Ansible
- SaltStack
- CloudFormation
- OpenStack Heat
Commands
Commands:
- get
- plan
- apply
- graph (use Graphviz to vizualize)
- destroy
AWS ENV:
AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY
Syntax
Input varaibles
variable "<name>" {
[description = "<description>"]
[default = <default value>]
[type = "<type>"]
}
Providing a variable value:
- command line (
-var,-var-file) - ENV variable (
TF_VAR_<variable name>) - default value
- user prompt
Type options (terrafomr can gues the type):
- string
- list
- map
Outputs variables
output "<name>" {
value = <value>
}
Data sources
A data source represents a piece of read-only information that is fetched from the provider.
Lifecycle
create_before_destroy: create a replacement resource before destroying the original.
Tips
Starting service on image setup:
resource "aws_instance" "app" {
...
user_data = <<-EOF
#!bin/bash
sudo service myservice start
EOF
}
user_data - a script that executes when the server is booting.
Don't put terraform state under version control
Problems:
- someone can forget to push it after changes was applied
- someone can forget to pull the latest version before applyying new changes
- all secrets are stored in plain text in state file
Use remote state storage. Available options:
- Amazon S3
- Azure storage
- HashiCorp Consul and Terraform Pro/Enterprise
- Terragrunt (s3 + ddb)
S3 remote storage:
provider "aws" {
region = "us-east-1"
}
resource "aws_s3_bucket" "terraform_state" {
bucket = "my-bucket-name"
versioning {
enabled = true
}
lifecycle {
prevent_destroy = true
}
}
terraform apply terraform remote config \ -backend=s3 \ -backend-config="bucket=my-bucket-name" \ -backend-config="key=global/s3/terraform.tfstate" \ -backend-config="region=us-east-1" \ -backend-config="encrypt=true"
Project structure and isolation
Use a folder per environment.
Resource folder:
main.tfvars.tfoutputs.tf
Templet files
Use templates files instead of interpolation, for large scripts.
Module versioning
Use versioning for modules.
Count
resource "aws_iam_user" "example" {
count = 10
name = "myuser.${count.index}"
}
Or
resource "aws_iam_user" "example" {
count = "${length(var.names)}"
name = "${element(var.names,count.index)}"
}
If statement
Use count.
Vocabulary
Infrastructure as Code
Infrastructure as Code (IAC) - write and execute code to define, deploy, and update your infrastructure.
Links
Terraform At Scale by Calvin French-Owen on YouTube
Terraform: Up and Running by Yevgeniy Brikman