presentations/terraform-workshop/index.md

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


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]

  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')