Difference between revisions of "Terraform"
(→Introduction) |
|||
Line 11: | Line 11: | ||
A high-level difference and/or reason to use Terraform over CAPS (Chef, [[Ansible]], Puppet, Salt) is that these others have a focus on automating the installation and configuration of software (i.e., keeping the machines in compliance and in a certain state). Terraform, however, can automate provisioning of the infrastructure itself (e.g., in AWS or Google). One can, of course, do the same with, say, Ansible. However, Terraform really shines in infrastructure management and automation. | A high-level difference and/or reason to use Terraform over CAPS (Chef, [[Ansible]], Puppet, Salt) is that these others have a focus on automating the installation and configuration of software (i.e., keeping the machines in compliance and in a certain state). Terraform, however, can automate provisioning of the infrastructure itself (e.g., in AWS or Google). One can, of course, do the same with, say, Ansible. However, Terraform really shines in infrastructure management and automation. | ||
+ | |||
+ | ==Examples== | ||
+ | ===Basic example=== | ||
+ | The following is a simple example of how to use Terraform to spin up a single [[:Category:AWS|AWS]] EC2 instance. | ||
+ | |||
+ | * Create a working directory (<code>aws.create_ec2_instance</code>) with the following files: | ||
+ | <pre> | ||
+ | aws.create_ec2_instance/ | ||
+ | ├── instance.tf | ||
+ | ├── provider.tf | ||
+ | ├── terraform.tfvars | ||
+ | └── vars.tf | ||
+ | </pre> | ||
+ | |||
+ | The contents of each of the above files should look like the following: | ||
+ | <pre> | ||
+ | $ cat << EOF >> instance.tf | ||
+ | resource "aws_instance" "example" { | ||
+ | ami = "${lookup(var.AMIS, var.AWS_REGION)}" | ||
+ | instance_type = "t2.micro" | ||
+ | } | ||
+ | EOF | ||
+ | |||
+ | $ cat << EOF >> provider.tf | ||
+ | provider "aws" { | ||
+ | access_key = "${var.AWS_ACCESS_KEY}" | ||
+ | secret_key = "${var.AWS_SECRET_KEY}" | ||
+ | region = "${var.AWS_REGION}" | ||
+ | } | ||
+ | EOF | ||
+ | |||
+ | $ cat << EOF >> terraform.tfvars | ||
+ | AWS_ACCESS_KEY = "<REDACTED>" | ||
+ | AWS_SECRET_KEY = "<REDACTED>" | ||
+ | EOF | ||
+ | |||
+ | $ cat << EOF >> vars.tf | ||
+ | variable "AWS_ACCESS_KEY" {} | ||
+ | variable "AWS_SECRET_KEY" {} | ||
+ | variable "AWS_REGION" { | ||
+ | default = "us-west-2" | ||
+ | } | ||
+ | variable "AMIS" { | ||
+ | type = "map" | ||
+ | default = { | ||
+ | us-west-2 = "ami-b2d463d2" | ||
+ | us-east-1 = "ami-13be557e" | ||
+ | eu-west-1 = "ami-0d729a60" | ||
+ | } | ||
+ | } | ||
+ | EOF | ||
+ | </pre> | ||
+ | |||
+ | * Now, "plan" your execution with: | ||
+ | <pre> | ||
+ | $ terraform plan | ||
+ | ... | ||
+ | + aws_instance.example | ||
+ | ami: "ami-b2d463d2" | ||
+ | associate_public_ip_address: "<computed>" | ||
+ | availability_zone: "<computed>" | ||
+ | ebs_block_device.#: "<computed>" | ||
+ | ephemeral_block_device.#: "<computed>" | ||
+ | instance_state: "<computed>" | ||
+ | instance_type: "t2.micro" | ||
+ | key_name: "<computed>" | ||
+ | network_interface_id: "<computed>" | ||
+ | placement_group: "<computed>" | ||
+ | private_dns: "<computed>" | ||
+ | private_ip: "<computed>" | ||
+ | public_dns: "<computed>" | ||
+ | public_ip: "<computed>" | ||
+ | root_block_device.#: "<computed>" | ||
+ | security_groups.#: "<computed>" | ||
+ | source_dest_check: "true" | ||
+ | subnet_id: "<computed>" | ||
+ | tenancy: "<computed>" | ||
+ | vpc_security_group_ids.#: "<computed>" | ||
+ | |||
+ | Plan: 1 to add, 0 to change, 0 to destroy. | ||
+ | </pre> | ||
+ | |||
+ | * Now, "apply" (or actually create the EC2 instance): | ||
+ | $ terraform apply | ||
==Bash completion== | ==Bash completion== |
Revision as of 21:48, 9 January 2017
Terraform is a tool for building, changing, and versioning infrastructure safely and efficiently. Terraform can manage existing and popular service providers as well as custom in-house solutions. It is a popular tool in DevOps.
Introduction
- Infrastructure as Code
- Used for the automation of your infrastructure
- It keeps your infrastructure in a certain state (compliant)
- E.g., 2 web instances and 2 volumes and 1 load balancer
- It makes your infrastructure auditable
- That is, you can keep your infrastructure change history in a version control system (e.g., git)
A high-level difference and/or reason to use Terraform over CAPS (Chef, Ansible, Puppet, Salt) is that these others have a focus on automating the installation and configuration of software (i.e., keeping the machines in compliance and in a certain state). Terraform, however, can automate provisioning of the infrastructure itself (e.g., in AWS or Google). One can, of course, do the same with, say, Ansible. However, Terraform really shines in infrastructure management and automation.
Examples
Basic example
The following is a simple example of how to use Terraform to spin up a single AWS EC2 instance.
- Create a working directory (
aws.create_ec2_instance
) with the following files:
aws.create_ec2_instance/ ├── instance.tf ├── provider.tf ├── terraform.tfvars └── vars.tf
The contents of each of the above files should look like the following:
$ cat << EOF >> instance.tf resource "aws_instance" "example" { ami = "${lookup(var.AMIS, var.AWS_REGION)}" instance_type = "t2.micro" } EOF $ cat << EOF >> provider.tf provider "aws" { access_key = "${var.AWS_ACCESS_KEY}" secret_key = "${var.AWS_SECRET_KEY}" region = "${var.AWS_REGION}" } EOF $ cat << EOF >> terraform.tfvars AWS_ACCESS_KEY = "<REDACTED>" AWS_SECRET_KEY = "<REDACTED>" EOF $ cat << EOF >> vars.tf variable "AWS_ACCESS_KEY" {} variable "AWS_SECRET_KEY" {} variable "AWS_REGION" { default = "us-west-2" } variable "AMIS" { type = "map" default = { us-west-2 = "ami-b2d463d2" us-east-1 = "ami-13be557e" eu-west-1 = "ami-0d729a60" } } EOF
- Now, "plan" your execution with:
$ terraform plan ... + aws_instance.example ami: "ami-b2d463d2" associate_public_ip_address: "<computed>" availability_zone: "<computed>" ebs_block_device.#: "<computed>" ephemeral_block_device.#: "<computed>" instance_state: "<computed>" instance_type: "t2.micro" key_name: "<computed>" network_interface_id: "<computed>" placement_group: "<computed>" private_dns: "<computed>" private_ip: "<computed>" public_dns: "<computed>" public_ip: "<computed>" root_block_device.#: "<computed>" security_groups.#: "<computed>" source_dest_check: "true" subnet_id: "<computed>" tenancy: "<computed>" vpc_security_group_ids.#: "<computed>" Plan: 1 to add, 0 to change, 0 to destroy.
- Now, "apply" (or actually create the EC2 instance):
$ terraform apply
Bash completion
$ cat << EOF >> /etc/bash_completion.d/terraform _terraform() { local cmds cur colonprefixes cmds="apply destroy fmt get graph import init \ output plan push refresh remote show taint \ untaint validate version state" COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} # Work-around bash_completion issue where bash interprets a colon # as a separator. # Work-around borrowed from the darcs work-around for the same # issue. colonprefixes=${cur%"${cur##*:}"} COMPREPLY=( $(compgen -W '$cmds' -- $cur)) local i=${#COMPREPLY[*]} while [ $((--i)) -ge 0 ]; do COMPREPLY[$i]=${COMPREPLY[$i]#"$colonprefixes"} done return 0 } && complete -F _terraform terraform EOF