This post contains the absolut essence from the Terraform Getting Started Guide: https://www.terraform.io/intro/getting-started/install.html
Preparation
brew install terraform
Create aws.tf
:
provider "aws" {
region = "us-east-1"
}
resource "aws_instance" "example" {
ami = "ami-2757f631" // https://cloud-images.ubuntu.com/locator/ec2/
instance_type = "t2.micro"
}
AMI = Amazon Machine Images
AWS credentials are stored in environment vars:
export AWS_ACCESS_KEY_ID=...
export AWS_SECRET_ACCESS_KEY=...
Init
$ terraform init
...
Terraform has been successfully initialized!
...
$ terraform plan -out planfile
+ aws_instance.example
ami: "ami-2757f631"
associate_public_ip_address: "<computed>"
...
$ terraform apply planfile
aws_instance.example: Creating...
...
aws_instance.example: Still creating... (10s elapsed)
aws_instance.example: Still creating... (20s elapsed)
aws_instance.example: Still creating... (30s elapsed)
aws_instance.example: Still creating... (40s elapsed)
aws_instance.example: Creation complete (ID: i-00b2e1a29daee4371)
$ terraform show
aws_instance.example:
id = i-00b2e1a29daee4371
ami = ami-2757f631
associate_public_ip_address = true
Change
ami-2757f631
(Ubuntu 16.04 LTS AMI) => ami-b374d5a5
(Ubuntu 16.10 AMI)
In aws.tf
:
provider "aws" {
region = "us-east-1"
}
resource "aws_instance" "example" {
ami = "ami-b374d5a5"
instance_type = "t2.micro"
}
$ terraform plan
Refreshing Terraform state in-memory prior to plan...
aws_instance.example: Refreshing state... (ID: i-00b2e1a29daee4371)
...
-/+ aws_instance.example (new resource required)
ami: "ami-2757f631" => "ami-b374d5a5" (forces new resource)
associate_public_ip_address: "true" => "<computed>"
...
$ terraform apply
aws_instance.example: Refreshing state... (ID: i-00b2e1a29daee4371)
aws_instance.example: Destroying... (ID: i-00b2e1a29daee4371)
...
aws_instance.example: Destruction complete
aws_instance.example: Creating...
ami: "" => "ami-b374d5a5"
associate_public_ip_address: "" => "<computed>"
...
aws_instance.example: Creation complete (ID: i-05a8f2e88ae0faace)
Destroy
$ terraform plan -destroy
Refreshing Terraform state in-memory prior to plan...
...
- aws_instance.example
...
$ terraform destroy
aws_instance.example: Refreshing state... (ID: i-05a8f2e88ae0faace)
...
- aws_instance.example
Terraform will delete all your managed infrastructure, as shown above.
There is no undo. Only 'yes' will be accepted to confirm.
Enter a value: yes
aws_instance.example: Destroying... (ID: i-05a8f2e88ae0faace)
aws_instance.example: Destruction complete
Destroy complete! Resources: 1 destroyed.
Assigning an IP to the instance
In aws.tf
:
provider "aws" {
region = "us-east-1"
}
resource "aws_instance" "example" {
ami = "ami-b374d5a5"
instance_type = "t2.micro"
}
resource "aws_eip" "ip" {
instance = "${aws_instance.example.id}"
}
$ terraform apply planfile
aws_instance.example: Creating...
...
aws_instance.example: Creation complete (ID: i-0478b3c5b6a085287)
aws_eip.ip: Creating...
...
aws_eip.ip: Creation complete (ID: eipalloc-6be79a58)
Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
$ terraform refresh
aws_instance.example: Refreshing state... (ID: i-0478b3c5b6a085287)
aws_eip.ip: Refreshing state... (ID: eipalloc-6be79a58)
$ terraform show
aws_eip.ip:
id = eipalloc-6be79a58
association_id = eipassoc-590d9e6c
domain = vpc
instance = i-0478b3c5b6a085287
network_interface = eni-73845aa6
private_ip = 172.31.17.98
public_ip = 52.204.255.194
vpc = true
aws_instance.example:
id = i-0478b3c5b6a085287
ami = ami-b374d5a5
associate_public_ip_address = true
Dependencies
The order in which resources are created is determined by terraforms analysis of (implicit) dependencies. Dependencies can also be defined explicitly, for example:
resource "aws_eip" "ip" {
instance = "${aws_instance.example.id}"
depends_on = ["aws_instance.example"] # <- explicit dependency
}
To view a dependency graph:
$ terraform graph > graph.dot
And open with graphviz:
Provisioning/Bootstrapping
Change aws.tf
:
resource "aws_instance" "example" {
ami = "ami-b374d5a5"
instance_type = "t2.micro"
# add provisioner
provisioner "local-exec" {
command = "echo ${aws_instance.example.public_ip} > ip_address.txt"
}
}
# add output
output "ip" {
value = "${aws_eip.ip.public_ip}"
}
Provisioners are only run, when a resource is first created!
$ terraform destroy
...
$ terraform apply
...
Outputs:
ip = 50.17.232.209