Terraform 10 of 10: Provisioners using AWS Cloud9
Background
This tutorial deals with Provisioners. AWS Cloud9 is the environment. Please note that Terraform only recommends Provisioners as a "last resort" and that you should attempt other methods before dealing with provisioners. Provisioners run within the resources themselves, so Provisioners add complexity and uncertainty.
1 of 14. Open the documentation for "Provisioners"
This documentation is not all-inclusive. You may find other documentation in the "Reference" section.
2 of 14. Open your AWS Cloud9 environment
3 of 14. Setup project directory and create files
Make sure to start from your "environment" before creating the directory. This directory will be used for this project. Make sure to run project operations from within that directory.
pwd
mkdir terraform-provisioners-example && cd terraform-provisioners-example
touch main.tf resources.tf outputs.tf
4 of 14. Generate SSH-Keys
ssh-keygen -f ec2-key
5 of 14. Modify terraform files: "main.tf", "resources.tf" and "outputs.tf"
"main.tf
provider "aws" {
region = "us-east-1"
}
"resources.tf". Keep in mind that the AMI is region-specific. This lab was run on this specific OS/image. It refers to the ssh key you previously made.
resource "aws_security_group" "example" {
name = "example"
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_key_pair" "key" {
key_name = "aws_tf_key"
public_key = file("./ec2-key.pub")
}
resource "aws_instance" "ec2" {
ami = "ami-0c7217cdde317cfec" #Canonical, Ubuntu, 22.04 LTS, amd64 jammy image build on 2023-12-07
instance_type = "t2.micro"
key_name = aws_key_pair.key.key_name
vpc_security_group_ids = [aws_security_group.example.id]
}
"outputs.tf"
output "ec2_pub_ip" {
value = aws_instance.ec2.public_ip
}
6 of 14. Create the resources
terraform init && terraform apply -auto-approve
7 of 14. Validate SSH
Note that the IP address here should match what was in the output of your 'terraform apply'
ssh -i ec2-key ubuntu@203.0.113.20
8 of 14. Destroy resources.
Make sure to exit your Ubuntu session first, else your command might not be understood.
exit
terraform destroy -auto-approve
9 of 14. Create a sample dump file
echo "This is a sample dump file" > dump
echo "Beep Boop Bleep Bloop Whoops!" >> dump
cat dump
10 of 14. Update "resources.tf" with provisioners.
Think of provisioners as running operations on the resource itself. All additions will be to the "ec2" resource, because these Provisioners run inside the ec2 instance itself. Look at the various types of commands: "local-exec" runs on the host running terraform. "remote-exec" is a remote command, "file" is a file operation. The "connection" refers to the connection that Terraform will make to the host to run the commands.
resource "aws_security_group" "example" {
name = "example"
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_key_pair" "key" {
key_name = "aws_tf_key"
public_key = file("./ec2-key.pub")
}
resource "aws_instance" "ec2" {
ami = "ami-0c7217cdde317cfec" #Canonical, Ubuntu, 22.04 LTS, amd64 jammy image build on 2023-12-07
instance_type = "t2.micro"
key_name = aws_key_pair.key.key_name
vpc_security_group_ids = [aws_security_group.example.id]
tags = {
"Name" = "webserver01"
}
provisioner "local-exec" {
command = "echo ${self.public_ip} >> ec2-public-ip.txt"
}
provisioner "file" {
source = "./dump" ## Do not forget to create fictitious 'dump' file
destination = "/tmp/dump-onp"
}
provisioner "file" {
content = "EC2 AZ: ${self.availability_zone}"
destination = "/tmp/ec2-az.txt"
}
provisioner "remote-exec" {
inline = [
"echo EC2 ARN: ${self.arn} >> /tmp/arn.txt",
"echo EC2 Public DNS: ${self.public_dns} >> /tmp/public_dns.txt",
"echo EC2 Private IP: ${self.private_ip} >> /tmp/private_ip.txt"
]
}
connection {
type = "ssh"
user = "ubuntu"
private_key = file("./ec2-key")
host = self.public_ip
}
}
11 of 14. Init and apply
This is a lab environment, but be wary of "auto-approve" in production unless it has been approved.
terraform fmt
terraform validate
terraform init && terraform apply -auto-approve
12 of 14. Check what ran for "local-exec"
Check for that "ec2-public-ip.txt" file
cat ec2-public-ip.txt
13 of 14. Check your Ubuntu host
Logon the Ubuntu host, then check for the created files and their contents. The previous warning about checking for the correct IP for your host before connecting still applies.
ssh -i ec2-key ubuntu@203.0.113.20
ls /tmp
cat /tmp/dump-onp
cat /tmp/ec2-az.txt
cat /tmp/arn.txt
cat /tmp/public_dns.txt
cat /tmp/private_ip.txt
14 of 14. Cleanup
>Cleanup what you did. Exit your Ubuntu host first. I could have auto-approved here also, but it's a habit I don't want to start.
exit
terraform destroy
Reference
Finding an Amazon Machine Image (AMI)
Comments
Post a Comment