presentations/terraform-workshop/index.md

192 lines
3.6 KiB
Markdown

# 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 (main.tf)
* Use `terraform init` to initialize
* Use `terraform plan` and `terraform apply` in order to deploy the resource
* Remove the resource by using `terraform destroy`
* Take advantage of terraform docs and providers:
* https://registry.terraform.io/ & https://developer.hashicorp.com/terraform
---
# 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 = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_key_pair" "my_key" {
key_name = "my-key-pair"
public_key = file("~/.ssh/my-key-pair.pub") # Path to your public key file
}
# Create an EC2 instance
resource "aws_instance" "my_ec2" {
ami = "ami-03e383d33727f4804"
instance_type = "t2.micro"
associate_public_ip_address = true
key_name = aws_key_pair.my_key.key_name
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')`