
To install terraform, refer to the respective documentation here
provider.tf in your directoryprovider "aws" {
region = "us-east-1"
}
terraform init
Initializing the backend...
Initializing provider plugins...
- Finding latest version of hashicorp/aws...
- Installing hashicorp/aws v3.61.0...
- Installed hashicorp/aws v3.61.0 (signed by HashiCorp)
Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.
Terraform has been successfully initialized!
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
# Data Source for getting Amazon Linux AMI
data "aws_ami" "amazon-2" {
most_recent = true
filter {
name = "name"
values = ["amzn2-ami-hvm-*-x86_64-ebs"]
}
owners = ["amazon"]
}
# Resource for podtatohead-main
resource "aws_instance" "podtatohead-main" {
ami = data.aws_ami.amazon-2.id
instance_type = "t3.micro"
tags = {
Name = "podtatohead-main"
}
}
# Resource for podtatohead-legs
resource "aws_instance" "podtatohead-legs" {
ami = data.aws_ami.amazon-2.id
instance_type = "t3.micro"
tags = {
Name = "podtatohead-legs"
}
}
# Resource for podtatohead-arms
resource "aws_instance" "podtatohead-arms" {
ami = data.aws_ami.amazon-2.id
instance_type = "t3.micro"
tags = {
Name = "podtatohead-arms"
}
}
# Resource for podtatohead-hats
resource "aws_instance" "podtatohead-hats" {
ami = data.aws_ami.amazon-2.id
instance_type = "t3.micro"
tags = {
Name = "podtatohead-hats"
}
}
terraform validate❯ terraform validate
Success! The configuration is valid.
terraform planPlan: 4 to add, 0 to change, 0 to destroy.
───────────────────────────────────────────────────────────────────────────────
Note: You didn't use the -out option to save this plan, so Terraform can't
guarantee to take exactly these actions if you run "terraform apply" now.
terraform applyterraform apply with the parameter --auto-approve (but be sure what you're doing).[...]
Plan: 4 to add, 0 to change, 0 to destroy.
aws_instance.podtatohead-main: Creating...
aws_instance.podtatohead-legs: Creating...
aws_instance.podtatohead-arms: Creating...
aws_instance.podtatohead-hats: Creating...
aws_instance.podtatohead-legs: Still creating... [10s elapsed]
aws_instance.podtatohead-main: Still creating... [10s elapsed]
aws_instance.podtatohead-arms: Still creating... [10s elapsed]
aws_instance.podtatohead-hats: Still creating... [10s elapsed]
aws_instance.podtatohead-main: Creation complete after 19s [id=i-0024742a855b87fe8]
aws_instance.podtatohead-arms: Creation complete after 19s [id=i-026ffc94cd3117a72]
aws_instance.podtatohead-hats: Creation complete after 19s [id=i-04183576772e51162]
aws_instance.podtatohead-legs: Creation complete after 19s [id=i-095392d47383309ba]
Apply complete! Resources: 4 added, 0 changed, 0 destroyed.

templates in your terraform directoryinit_hats.tpl in the templates directory and add the following:#!/bin/bash
sudo yum update -y
sudo amazon-linux-extras install docker -y
sudo service docker start
sudo usermod -a -G docker ec2-user
sudo docker run -p 8080:8080 -e PORT=8080 -e VERSION=${version} -d ${container_image}:${podtato_version}
init.tpl (for the legs and arms)#!/bin/bash
sudo yum update -y
sudo amazon-linux-extras install docker -y
sudo service docker start
sudo usermod -a -G docker ec2-user
sudo docker run -p 8080:8080 -e PORT=8080 -e LEFT_VERSION=${left_version} -e RIGHT_VERSION=${right_version} -d ${container_image}:${podtato_version}
init_main.tpl (for main)#!/bin/bash
sudo yum update -y
sudo amazon-linux-extras install docker -y
sudo service docker start
sudo usermod -a -G docker ec2-user
sudo docker run -p 8080:8080 -e PORT=8080 -e HATS_HOST=${hats_host} -e HATS_PORT=8080 -e ARMS_HOST=${arms_host} -e ARMS_PORT=8080 -e LEGS_HOST=${legs_host} -e LEGS_PORT=8080 -d ${container_image}:${podtato_version}
main.tf file in your Terraform folderpodtatohead-main resource user_data = templatefile("${path.module}/templates/init_main.tpl", { container_image = "ghcr.io/fhb-codelabs/podtato-small-main", hats_host = aws_instance.podtatohead-hats.private_ip, arms_host = aws_instance.podtatohead-arms.private_ip, legs_host = aws_instance.podtatohead-legs.private_ip, podtato_version=var.podtato_version } )
podtatohead-legs resource user_data = templatefile("${path.module}/templates/init.tpl", { container_image = "ghcr.io/fhb-codelabs/podtato-small-legs", podtato_version=var.podtato_version, left_version=var.left_leg_version, right_version=var.right_leg_version} )
resource "aws_instance" "podtatohead-main" {
ami = data.aws_ami.amazon-2.id
instance_type = "t3.micro"
user_data = templatefile("${path.module}/templates/init_main.tpl", { container_image = "ghcr.io/fhb-codelabs/podtato-small-main", hats_host = aws_instance.podtatohead-hats.private_ip, arms_host = aws_instance.podtatohead-arms.private_ip, legs_host = aws_instance.podtatohead-legs.private_ip, podtato_version=var.podtato_version } )
tags = {
Name = "podtatohead-main"
}
}
podtatohead-arms resource user_data = templatefile("${path.module}/templates/init.tpl", { container_image = "ghcr.io/fhb-codelabs/podtato-small-arms", podtato_version=var.podtato_version, left_version=var.left_arm_version, right_version=var.right_arm_version } )
podtatohead-hats resource user_data = templatefile("${path.module}/templates/init_hats.tpl", { container_image = "ghcr.io/fhb-codelabs/podtato-small-hats", podtato_version=var.podtato_version, version=var.hats_version } )
terraform validateError: Reference to undeclared input variable
│
│ on main.tf line 30, in resource "aws_instance" "podtatohead-legs":
│ 30: user_data = templatefile("${path.module}/templates/init.tpl", { container_image = "ghcr.io/fhb-codelabs/podtato-small-legs", podtato_version=var.podtato_version, left_version=var.left_leg_version, right_version=var.right_leg_version} )
│
│ An input variable with the name "podtato_version" has not been declared. This
│ variable can be declared with a variable "podtato_version" {} block.
vars.tf in your terraform foldervariable "podtato_version" {
type = string
}
variable "hats_version" {
type = string
}
variable "left_arm_version" {
type = string
}
variable "right_arm_version" {
type = string
}
variable "right_leg_version" {
type = string
}
variable "left_leg_version" {
type = string
}
terraform.tfvars in your terraform directory and add the following contentpodtato_version="v0.1.0"
left_arm_version = "v1"
right_arm_version = "v2"
left_leg_version = "v3"
right_leg_version = "v3"
hats_version = "v4"
terraform validate should pass nowterraform plan and inspect the output:[...]
Plan: 4 to add, 0 to change, 4 to destroy.
───────────────────────────────────────────────────────────────────────────────
Note: You didn't use the -out option to save this plan, so Terraform can't
guarantee to take exactly these actions if you run "terraform apply" now.
terraform apply
security_group resource and assign it to an instance.main.tf file:resource "aws_security_group" "ingress-all-ssh" {
name = "allow-all-ssh"
ingress {
cidr_blocks = [
"0.0.0.0/0"
]
from_port = 22
to_port = 22
protocol = "tcp"
}
// Terraform removes the default rule
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_security_group" "ingress-all-http" {
name = "allow-all-http"
ingress {
cidr_blocks = [
"0.0.0.0/0"
]
from_port = 8080
to_port = 8080
protocol = "tcp"
}
// Terraform removes the default rule
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
vpc_security_group_ids = [aws_security_group.ingress-all-ssh.id, aws_security_group.ingress-all-http.id]
resource "aws_instance" "podtatohead-main" {
ami = data.aws_ami.amazon-2.id
instance_type = "t3.micro"
user_data = templatefile("${path.module}/templates/init_main.tpl", { container_image = "ghcr.io/fhb-codelabs/podtato-small-main", hats_host = aws_instance.podtatohead-hats.private_ip, arms_host = aws_instance.podtatohead-arms.private_ip, legs_host = aws_instance.podtatohead-legs.private_ip, podtato_version=var.podtato_version } )
vpc_security_group_ids = [aws_security_group.ingress-all-ssh.id, aws_security_group.ingress-all-http.id]
tags = {
Name = "podtatohead-main"
}
lifecycle {
create_before_destroy = true
}
}
terraform validateterraform planterraform applyoutputs.tf in your Terraform directory with the following contentsoutput "podtato-url" {
value = "http://${aws_instance.podtatohead-main.public_ip}:8080"
}
terraform refresh to update the statepodtato-url which can be put in a browser, simply try to do this
terraform destroy