terraform-infrastructure-as-code
Included with Lifetime
$97 forever
Comprehensive Terraform Infrastructure as Code skill covering resources, modules, state management, workspaces, providers, and advanced patterns for cloud-agnostic infrastructure deployment
Infrastructureterraforminfrastructure-as-codeclouddevopsautomationawsazuregcp
What this skill does
# Terraform Infrastructure as Code - Comprehensive Guide
## Table of Contents
1. [Introduction to Terraform](#introduction-to-terraform)
2. [Core Concepts](#core-concepts)
3. [Resources](#resources)
4. [Data Sources](#data-sources)
5. [Variables and Outputs](#variables-and-outputs)
6. [Modules](#modules)
7. [State Management](#state-management)
8. [Workspaces](#workspaces)
9. [Provider Configuration](#provider-configuration)
10. [Advanced Features](#advanced-features)
11. [Dependencies](#dependencies)
12. [Provisioners](#provisioners)
13. [Best Practices](#best-practices)
14. [CI/CD Integration](#cicd-integration)
## Introduction to Terraform
Terraform is an open-source Infrastructure as Code (IaC) tool created by HashiCorp that enables you to define and provision infrastructure using a declarative configuration language called HashiCorp Configuration Language (HCL). Terraform manages external resources such as public cloud infrastructure, private cloud infrastructure, network appliances, and software as a service.
### Key Benefits
- **Declarative Configuration**: Define what your infrastructure should look like, not how to create it
- **Cloud-Agnostic**: Works with multiple cloud providers and services
- **Version Control**: Infrastructure code can be versioned and reviewed
- **Plan Before Apply**: Preview changes before applying them
- **Resource Graph**: Automatically manages dependencies between resources
- **State Management**: Tracks the current state of your infrastructure
### Terraform Workflow
```bash
# Initialize Terraform working directory
terraform init
# Initialize and upgrade provider versions
terraform init -upgrade
# Initialize with backend configuration
terraform init -backend-config="bucket=my-state-bucket"
# Generate a plan
terraform plan
# Save plan to file for later apply
terraform plan -out=tfplan
# Plan with specific variable values
terraform plan -var="region=us-west-2" -var="instance_type=t2.micro"
# Apply with interactive approval
terraform apply
# Auto-approve without confirmation
terraform apply -auto-approve
# Apply a saved plan file
terraform apply tfplan
# Destroy with confirmation prompt
terraform destroy
# Auto-approve destruction
terraform destroy -auto-approve
```
## Core Concepts
### 1. Resources
Resources are the most fundamental elements in Terraform. They represent infrastructure objects like virtual machines, networks, databases, or DNS records.
```hcl
# Basic resource declaration
resource "aws_instance" "web" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
tags = {
Name = "WebServer"
Environment = "production"
}
}
```
### 2. Providers
Providers are plugins that allow Terraform to interact with cloud platforms, SaaS providers, and other APIs.
```hcl
# AWS provider configuration
provider "aws" {
region = "us-west-2"
default_tags {
tags = {
ManagedBy = "Terraform"
Project = "MyApp"
}
}
}
```
### 3. State
Terraform stores information about your infrastructure in a state file. This state is used to map real-world resources to your configuration and track metadata.
### 4. Configuration Language (HCL)
HCL is designed to be both human-readable and machine-friendly, making it ideal for infrastructure configuration.
## Resources
Resources are the building blocks of Terraform configurations. Each resource block describes one or more infrastructure objects.
### Basic Resource Syntax
```hcl
resource "resource_type" "resource_name" {
argument1 = "value1"
argument2 = "value2"
nested_block {
nested_argument = "nested_value"
}
}
```
### Resource Examples
#### AWS EC2 Instance
```hcl
resource "aws_instance" "app_server" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
key_name = "my-keypair"
vpc_security_group_ids = [aws_security_group.app.id]
subnet_id = aws_subnet.public.id
user_data = <<-EOF
#!/bin/bash
echo "Hello, World!" > index.html
nohup busybox httpd -f -p 8080 &
EOF
tags = {
Name = "AppServer"
Environment = "production"
ManagedBy = "Terraform"
}
}
```
#### AWS VPC
```hcl
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
enable_dns_support = true
tags = {
Name = "main-vpc"
}
}
resource "aws_subnet" "public" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.1.0/24"
availability_zone = "us-west-2a"
map_public_ip_on_launch = true
tags = {
Name = "public-subnet"
}
}
resource "aws_subnet" "private" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.2.0/24"
availability_zone = "us-west-2a"
tags = {
Name = "private-subnet"
}
}
```
#### AWS S3 Bucket
```hcl
resource "aws_s3_bucket" "data" {
bucket = "my-app-data-bucket-12345"
tags = {
Name = "Data Bucket"
Environment = "production"
}
}
resource "aws_s3_bucket_versioning" "data" {
bucket = aws_s3_bucket.data.id
versioning_configuration {
status = "Enabled"
}
}
resource "aws_s3_bucket_server_side_encryption_configuration" "data" {
bucket = aws_s3_bucket.data.id
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "AES256"
}
}
}
```
#### AWS Security Group
```hcl
resource "aws_security_group" "web" {
name = "web-sg"
description = "Security group for web servers"
vpc_id = aws_vpc.main.id
ingress {
description = "HTTP from anywhere"
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
description = "HTTPS from anywhere"
from_port = 443
to_port = 443
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"]
}
tags = {
Name = "web-security-group"
}
}
```
### Resource Lifecycle
```hcl
resource "aws_instance" "example" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
lifecycle {
create_before_destroy = true
prevent_destroy = true
ignore_changes = [tags]
}
}
```
**Lifecycle options:**
- `create_before_destroy`: Create new resource before destroying the old one
- `prevent_destroy`: Prevent accidental destruction of resources
- `ignore_changes`: Ignore changes to specified attributes
- `replace_triggered_by`: Force replacement when specific resources change
```hcl
resource "aws_instance" "example" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
lifecycle {
replace_triggered_by = [
aws_iam_policy.example.id
]
}
}
```
## Data Sources
Data sources allow Terraform to use information defined outside of Terraform, or defined by another separate Terraform configuration.
### Data Source Syntax
```hcl
data "resource_type" "name" {
# Query parameters
}
```
### Data Source Examples
```hcl
# Query existing AWS resources
data "aws_ami" "ubuntu" {
most_recent = true
owners = ["099720109477"] # Canonical
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"]
}
}
# Use data source in resource
resource "aws_instance" "web" {
ami = data.aws_ami.ubuntu.id
instance_type = "t2.micro"
}
# Query availability zones
data "aws_availability_zones" "available" {
state = "available"
}
# Query VPC
data "aws_vpc" "default" {
default = true
}
# Query remote state
data "terraform_remote_state" "network" {
backend = "s3"
config = {
bucket = "terraform-state"
key = "network/terraform.tfstate"
region = "us-west-2"
}
}
# Use remote state outputs
resource "aws_instance" "app" {
ami = data.aws_ami.ubuntu.id
instance_type = "t2.micro"
subnet_id = data.terraform_remote_state.network.outputs.subnet_id
availability_zon