3.4 KiB
Terraform Workshop
What is Terraform
IaC (Infrastructure as Code) framework which enables programatic definition, deployment and management of infrastructure resources for cloud and on-premises in a declarative manner. It targets all major cloud platforms (GCP, AWS, Azure, DO etc.)
Why do We Need it
-
Standardization of deployment to ensure a consistent state
- Version control
- Deploying an additional clone env for testing
-
Easier auditability to improve quality and security
- Modular - reuse & ease of understanding
- Resource Graph (dependency graph + parallel execution when possible)
- Version control
-
Enables use of hardened deployment pipelines
-
Enables immutable infrastructure
Human-Readible Configuration Language
HashiCorp Configuration Language (HCL) or JSON
provider "aws" {
region = "us-west-2"
}
resource "aws_instance" "example" {
ami = "ami-0c55b159cbfafe1f0" # Amazon Linux 2 AMI ID
instance_type = "t2.micro"
tags = {
Name = "HelloWorldEC2Instance"
}
}
output "instance_public_ip" {
value = aws_instance.example.public_ip
}
Workflow
-
Write your configuration file
-
Use
terraform init
to initialize a Terraform workspace -
Use the the
terraform plan
action to simulate deployment of resources and assess the outcome -
Use
terraform apply
to actually deploy resources
Exercise
-
Set up local credentials for your cloud platform of choice
-
Write a file that deploys an EC2 instance
-
Use
terraform plan
andterraform apply
in order to deploy the resource -
Remove the resource by using
terraform destroy
-
Take advantage of terraform docs and providers:
Solution
# Specify the provider
provider "aws" {
region = "us-west-2"
}
# Create an EC2 instance
resource "aws_instance" "my_ec2" {
ami = "ami-03e383d33727f4804"
instance_type = "t2.micro"
tags = {
Name = "TestEC2Instance"
}
}
Extend Configuration
-
Add a VPC
-
Define security group that limits ingress and egress to port 22
-
Add SSH key(s) which may connect to the instance
Solution
# Specify the provider
provider "aws" {
region = "us-west-2"
}
# Create a security group
resource "aws_security_group" "allow_ssh" {
name = "allow_ssh"
description = "Allow SSH access"
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_security_group" "default_egress" {
name = "default_egress"
description = "Specify egress for instance"
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
# Specify the provider
provider "aws" {
region = "us-west-2"
}
# Create an EC2 instance
resource "aws_instance" "my_ec2" {
ami = "ami-03e383d33727f4804"
instance_type = "t2.micro"
security_groups = [
aws_security_group.allow_ssh.name,
aws_security_grou.default_egress.name
]
tags = {
Name = "TestEC2Instance"
}
}
Additional Notes
- Typically the terraform state is stored online in a manner that makes it retrievable by others
SOPS for Secrets Management
-
Download from https://github.com/getsops/sops
-
Encrypt config file:
sops -e --pgp <key_id> credentials > credentials.enc
-
Decrypt and set:
eval $(sops -d credentials.enc | sed 's/: /=/g')