Terraform ¶
Terraform is a tool for building, changing, and versioning infrastructure safely and efficiently. Terraform can help with multi-cloud by having one workflow for all clouds. The infrastructure Terraform manages can be hosted on public clouds like Amazon Web Services, Microsoft Azure, and Google Cloud Platform, or on-prem in private clouds such as VMWare vSphere.
Terraform Installation ๐ฅ¶
curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add -
sudo apt-add-repository "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main"
sudo apt-get update && sudo apt-get install terraform
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo
sudo yum -y install terraform
Reference ๐¶
Terraform Registry
Terraform Commands Cheat sheet Reference Link
https://acloudguru.com/blog/engineering/the-ultimate-terraform-cheatsheet
Prerequisites¶
Before you begin, ensure you have the following prerequisites in place:
-
AWS Account: You need an active AWS account with necessary permissions to create resources like Ec2 Instances, IAM roles, VPC, etc.
-
AWS CLI: Install and configure the AWS Command Line Interface (CLI) on your local machine. You can download it from the AWS CLI Documentation.
-
IAM User: Create an AWS IAM user with programmatic access and necessary permissions (e.g., Ec2 Full Access, S3 Full Access). Note down the user's access key ID and secret access key. ๐ Reference Document Link
Warning
Utilize Role-Based Authentication when working with Terraform on AWS Instances or Services, as it offers a higher level of security compared to using access keys.
Terraform Sample Scripts¶
Provisioning an AWS EC2 Instance
provider "aws" {
region = "us-east-2"
}
resource "aws_instance" "Instance" {
ami = "ami-0fb653ca2d3203ac1"
instance_type = "t2.micro"
key_name = "terraform"
vpc_security_group_ids = ["sg-0138c7796472ac9a9"]
tags = {
Name = "IAAC"
Team = "DevOps"
}
}
provider "aws" {
region = "us-east-1"
}
resource "aws_key_pair" "example_keypair" {
key_name = "satrun"
public_key = tls_private_key.example_keypair.public_key_openssh
}
resource "tls_private_key" "example_keypair" {
algorithm = "RSA"
}
resource "local_file" "private_key_file" {
content = tls_private_key.example_keypair.private_key_pem
filename = "satrun.pem"
}
resource "aws_security_group" "example_security_group" {
name = "satrun-security-group"
description = "Example Security Group"
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["YOUR PUBLIC IP/32"]
}
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["YOUR PUBLIC IP/32"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_instance" "example_instance" {
ami = "ami-09e67e426f25ce0d7" # Ubuntu 20.04 LTS in us-east-1 (N. Virginia) region
instance_type = "t2.micro"
key_name = aws_key_pair.example_keypair.key_name
vpc_security_group_ids = [aws_security_group.example_security_group.id]
tags = {
Name = "satrun-instance"
}
}
Terraform Vars¶
Using Variables
Create a File with name vars.tf
vim vars.tf
variable "REGION" {
default = "us-east-2"
}
variable "ZONE1" {
default = "us-east-2a"
}
variable "AMIS" {
type = map(any)
default = {
us-east-2 = "ami-0fb653ca2d3203ac1"
us-east-1 = "ami-0e1d30f2c40c4c701"
}
}
Terraform Provider¶
Example for AWS
vim provider.tf
provider "aws" {
region = var.REGION
}
Launching Instance with Vars File
vim main.tf
resource "aws_instance" "Instance" {
ami = var.AMIS[var.REGION]
instance_type = "t2.micro"
key_name = "terraform"
vpc_security_group_ids = ["sg-0138c7796472ac9a9"]
tags = {
Name = "IAAC"
Team = "DevOps"
}
}
Terraform Provisioning¶
Launching AWS Resources and Setting Up a Website with Terraform with existing key-pair
Note
Generate a key pair using the 'ssh-keygen' command and then save the contents of the public and private keys into two new files named 'testing007.pub' and 'testing007'.
resource "aws_key_pair" "testing007" {
key_name = "testing007"
public_key = file("testing007.pub")
}
resource "aws_instance" "Instance" {
ami = var.AMIS[var.REGION]
instance_type = "t2.micro"
key_name = aws_key_pair.testing007.key_name
vpc_security_group_ids = ["sg-0138c7796472ac9a9"]
tags = {
Name = "IAAC"
Team = "DevOps"
}
provisioner "file" {
source = "./web.sh"
destination = "/tmp/web.sh"
}
provisioner "remote-exec" {
inline = [
"chmod u+x /tmp/web.sh",
"sudo /tmp/web.sh"
]
}
connection {
user = var.USER
private_key = file("testing007")
host = self.public_ip
}
}
output "PublicIP" {
value = aws_instance.Instance.public_ip
}
Variables file - vars.tf
variable "REGION" {
default = "us-east-2"
}
variable "ZONE1" {
default = "us-east-2a"
}
variable "USER" {
default = "ubuntu"
}
variable "AMIS" {
type = map(any)
default = {
us-east-2 = "ami-0fb653ca2d3203ac1"
us-east-1 = "ami-0e1d30f2c40c4c701"
}
}
To Store State Remotely in S3 Bucket¶
Create an S3 Bucket
terraform {
backend "s3" {
bucket = "terraform-state-009"
key = "terraform/remote"
region = "us-east-1"
}
}
Running Terraform Script using Pipeline¶
Launching EC2 Instances and Storing State Files in an S3 Bucket with Terraform
Info
Enable Authentications such as service connections, OAuth Tokens and etc of the required platform with your pipeline
provider "aws" {
region = "us-east-1"
}
resource "aws_key_pair" "example_keypair" {
key_name = "mars"
public_key = tls_private_key.example_keypair.public_key_openssh
}
resource "tls_private_key" "example_keypair" {
algorithm = "RSA"
}
resource "local_file" "private_key_file" {
content = tls_private_key.example_keypair.private_key_pem
filename = "mars.pem"
}
resource "aws_security_group" "example_security_group" {
name = "mars-security-group"
description = "Example Security Group"
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["183.82.115.199/32"]
}
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["183.82.115.199/32"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_instance" "example_instance" {
ami = "ami-09e67e426f25ce0d7" # Ubuntu 20.04 LTS in us-east-1 (N. Virginia) region
instance_type = "t2.micro"
key_name = aws_key_pair.example_keypair.key_name
vpc_security_group_ids = [aws_security_group.example_security_group.id]
tags = {
Name = "mars-instance"
}
}
terraform {
backend "s3" {
bucket = "terraform-azuredevops-saitejairrinki-org"
key = "terraform/remote"
region = "us-east-1"
}
}
provider "aws" {
region = "us-east-1"
}
resource "aws_key_pair" "example_keypair" {
key_name = "satrun"
public_key = tls_private_key.example_keypair.public_key_openssh
}
resource "tls_private_key" "example_keypair" {
algorithm = "RSA"
}
resource "local_file" "private_key_file" {
content = tls_private_key.example_keypair.private_key_pem
filename = "satrun.pem"
}
resource "aws_security_group" "example_security_group" {
name = "satrun-security-group"
description = "Example Security Group"
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_instance" "example_instance" {
ami = "ami-09e67e426f25ce0d7" # Ubuntu 20.04 LTS in us-east-1 (N. Virginia) region
instance_type = "t2.micro"
key_name = aws_key_pair.example_keypair.key_name
vpc_security_group_ids = [aws_security_group.example_security_group.id]
tags = {
Name = "satrun-instance"
}
provisioner "file" {
source = "./web.sh"
destination = "/tmp/web.sh"
}
provisioner "remote-exec" {
inline = [
"chmod +x /tmp/web.sh",
"sudo /tmp/web.sh"
]
}
connection {
type = "ssh"
user = "ubuntu" # Change to the appropriate SSH user for your AMI
private_key = tls_private_key.example_keypair.private_key_pem
host = self.public_ip
}
}
output "PublicIP" {
value = aws_instance.example_instance.public_ip
}
terraform {
backend "s3" {
bucket = "1terraform"
key = "terraform/remote"
region = "us-east-1"
}
}