Terraform: Difference between revisions
(Created page with "= Terraform Basics and Best Practices = ''This page covers Terraform fundamentals, best practices, essential commands, and deployment examples for AWS.'' == Introduction == Terraform is an Infrastructure as Code (IaC) tool used to provision, manage, and automate cloud infrastructure. It enables declarative configuration, making infrastructure deployments more reliable and consistent. == Best Practices == === 1. Use Remote Backend for State Management === Terraform sto...") |
No edit summary |
||
(4 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
= | = Summary = | ||
Terraform is an open-source Infrastructure as Code (IaC) tool developed by HashiCorp. It allows you to define and provision infrastructure using a declarative configuration language called HCL (HashiCorp Configuration Language). | |||
Terraform is an Infrastructure as Code (IaC) tool | |||
= Best Practices = | |||
== | == Use Remote Backend for State Management == | ||
Terraform stores state to track infrastructure changes. A remote backend (e.g., | Terraform stores state to track infrastructure changes. A remote backend (e.g., S3 + DynamoDB) ensures consistency and team collaboration. | ||
Example (backend.tf): | |||
< | <pre> | ||
terraform { | terraform { | ||
backend "s3" { | backend "s3" { | ||
Line 21: | Line 19: | ||
} | } | ||
} | } | ||
</ | </pre> | ||
== | == Use Modules for Reusability == | ||
Organizing infrastructure as modules makes it easier to maintain and reuse components. | Organizing infrastructure as modules makes it easier to maintain and reuse components. | ||
Example Directory Structure: | |||
<pre> | <pre> | ||
terraform/ | terraform/ | ||
Line 40: | Line 38: | ||
</pre> | </pre> | ||
== | == Use Workspaces for Multi-Environment Management == | ||
Workspaces allow Terraform to manage multiple environments within the same configuration. | Workspaces allow Terraform to manage multiple environments within the same configuration. | ||
Commands to Create and Switch Workspaces: | |||
< | <pre> | ||
terraform workspace new dev | terraform workspace new dev | ||
terraform workspace select dev | terraform workspace select dev | ||
terraform apply | terraform apply | ||
</ | </pre> | ||
To switch to a different environment: | |||
<pre> | |||
terraform workspace select prod | |||
terraform apply | |||
</pre> | |||
Using workspaces ensures that your environments (e.g., dev, prod, test) are separated, and each has its own isolated state file. This approach is particularly useful when you want to use the same configuration for different environments, but each environment's state is kept separate. | |||
Example of Workspace-specific Variables: | |||
<pre> | |||
# terraform.tfvars for dev | |||
aws_region = "us-east-1" | |||
cidr_block = "10.0.0.0/16" | |||
# terraform.tfvars for prod | |||
aws_region = "us-west-2" | |||
cidr_block = "10.1.0.0/16" | |||
</pre> | |||
Now, you can have different sets of configurations for dev, prod, and test environments with environment-specific variables that can be managed with different workspaces. | |||
== | == Secure Secrets and Sensitive Data == | ||
Use Terraform variables with `sensitive = true` and AWS Secrets Manager. | Use Terraform variables with `sensitive = true` and AWS Secrets Manager. | ||
Example (variables.tf): | |||
< | <pre> | ||
variable "db_password" { | variable "db_password" { | ||
description = "Database password" | description = "Database password" | ||
Line 60: | Line 79: | ||
sensitive = true | sensitive = true | ||
} | } | ||
</ | </pre> | ||
= Essential Terraform Commands = | |||
These commands are used in most Terraform workflows. | These commands are used in most Terraform workflows. | ||
== Initialization: == | |||
< | <pre> | ||
terraform init | terraform init | ||
</ | </pre> | ||
== Plan the deployment: == | |||
< | <pre> | ||
terraform plan -var="aws_region=us-east-1" | terraform plan -var="aws_region=us-east-1" | ||
</ | </pre> | ||
== Apply changes: == | |||
< | <pre> | ||
terraform apply -var="aws_region=us-east-1" -auto-approve | terraform apply -var="aws_region=us-east-1" -auto-approve | ||
</ | </pre> | ||
== Check Terraform state: == | |||
< | <pre> | ||
terraform state list | terraform state list | ||
</ | </pre> | ||
== Destroy resources: == | |||
< | <pre> | ||
terraform destroy -var="aws_region=us-east-1" -auto-approve | terraform destroy -var="aws_region=us-east-1" -auto-approve | ||
</ | </pre> | ||
= Deploying an AWS VPC = | |||
This example provisions a | This example provisions a VPC with public and private subnets. | ||
== VPC Module (vpc.tf): == | |||
< | <pre> | ||
module "vpc" { | module "vpc" { | ||
source = "./modules/vpc" | source = "./modules/vpc" | ||
Line 103: | Line 122: | ||
private_subnets = ["10.0.3.0/24", "10.0.4.0/24"] | private_subnets = ["10.0.3.0/24", "10.0.4.0/24"] | ||
} | } | ||
</ | </pre> | ||
== VPC Module (modules/vpc/main.tf): == | |||
< | <pre> | ||
resource "aws_vpc" "main" { | resource "aws_vpc" "main" { | ||
cidr_block = var.cidr_block | cidr_block = var.cidr_block | ||
Line 113: | Line 132: | ||
} | } | ||
} | } | ||
</ | </pre> | ||
== Variables (modules/vpc/variables.tf): == | |||
< | <pre> | ||
variable "vpc_name" { type = string } | variable "vpc_name" { type = string } | ||
variable "cidr_block" { type = string } | variable "cidr_block" { type = string } | ||
variable "public_subnets" { type = list(string) } | variable "public_subnets" { type = list(string) } | ||
variable "private_subnets" { type = list(string) } | variable "private_subnets" { type = list(string) } | ||
</ | </pre> | ||
= Deploying a Terraform CI/CD Pipeline = | |||
A Terraform CI/CD pipeline ensures consistent and automated deployments. This example uses AWS CodePipeline. | A Terraform CI/CD pipeline ensures consistent and automated deployments. This example uses AWS CodePipeline. | ||
== Pipeline Stages: == | |||
* '''Source''' – Fetch Terraform code from Bitbucket. | |||
* '''Plan''' – Run `terraform plan`. | |||
* '''Approve''' – Manual approval for `prod`. | |||
* '''Apply''' – Run `terraform apply`. | |||
== Pipeline Definition (pipeline.tf): == | |||
< | <pre> | ||
resource "aws_codepipeline" "terraform_pipeline" { | resource "aws_codepipeline" "terraform_pipeline" { | ||
name = "terraform-deploy" | name = "terraform-deploy" | ||
Line 193: | Line 212: | ||
} | } | ||
} | } | ||
</ | </pre> | ||
= Security Best Practices = | |||
* '''Enable AWS Config & GuardDuty''' – Monitor changes and security threats. | |||
* '''Encrypt sensitive data''' – Use '''AWS KMS''' for encrypting resources. | |||
* '''Use private subnets''' – Keep sensitive resources off the public internet. | |||
* '''Use IAM roles with least privilege access.''' | |||
= Conclusion = | |||
By following these Terraform best practices for AWS, you ensure a '''secure''', '''scalable''', and '''efficient''' infrastructure. Keep your Terraform setup '''modular''', '''automated''', and '''well-documented'''. | |||
== Deploying with Workspaces for Environment Separation == | |||
Workspaces are useful when you want to maintain environment separation in a single Terraform configuration. For example, each environment (dev, test, prod) would have its own workspace, ensuring separate state files and variable configurations. | |||
Steps to Deploy Using Workspaces: | |||
1. Create and switch to a workspace: | |||
<pre> | |||
terraform workspace new dev | |||
terraform workspace select dev | |||
terraform apply | |||
</pre> | |||
2. Apply changes in the dev environment: | |||
<pre> | |||
terraform apply | |||
</pre> | |||
3. Switch to the production workspace and apply: | |||
<pre> | |||
terraform workspace select prod | |||
terraform apply | |||
</pre> | |||
By using workspaces, you separate your environments' state files, making it easier to manage infrastructure across multiple environments. Each workspace can have different configurations or even different variables. | |||
== Deploying Without Workspaces == | |||
If you don't want to use workspaces and want to deploy in different environments without this separation, you can use distinct `terraform.tfvars` files or specify variables directly in the command line. | |||
For example: | |||
1. In the dev environment, you could specify variables like so: | |||
<pre> | |||
terraform apply -var="aws_region=us-east-1" -var="cidr_block=10.0.0.0/16" | |||
</pre> | |||
== | 2. For production, you can specify a different set of variables: | ||
<pre> | |||
terraform apply -var="aws_region=us-west-2" -var="cidr_block=10.1.0.0/16" | |||
</pre> | |||
This method doesn’t use workspaces but still allows different configurations for different environments by passing the relevant variables during the apply phase. | |||
--- | --- | ||
'''''Retrieved from your Terraform Wiki''''' | '''''Retrieved from your Terraform Wiki''''' |
Latest revision as of 14:41, 3 February 2025
Summary
Terraform is an open-source Infrastructure as Code (IaC) tool developed by HashiCorp. It allows you to define and provision infrastructure using a declarative configuration language called HCL (HashiCorp Configuration Language).
Best Practices
Use Remote Backend for State Management
Terraform stores state to track infrastructure changes. A remote backend (e.g., S3 + DynamoDB) ensures consistency and team collaboration.
Example (backend.tf):
terraform { backend "s3" { bucket = "my-terraform-state" key = "envs/prod/terraform.tfstate" region = "us-east-1" dynamodb_table = "terraform-lock" encrypt = true } }
Use Modules for Reusability
Organizing infrastructure as modules makes it easier to maintain and reuse components.
Example Directory Structure:
terraform/ ├── modules/ │ ├── vpc/ │ ├── ec2/ │ ├── rds/ │ ├── s3/ ├── environments/ │ ├── dev/ │ ├── prod/ │ ├── test/
Use Workspaces for Multi-Environment Management
Workspaces allow Terraform to manage multiple environments within the same configuration.
Commands to Create and Switch Workspaces:
terraform workspace new dev terraform workspace select dev terraform apply
To switch to a different environment:
terraform workspace select prod terraform apply
Using workspaces ensures that your environments (e.g., dev, prod, test) are separated, and each has its own isolated state file. This approach is particularly useful when you want to use the same configuration for different environments, but each environment's state is kept separate.
Example of Workspace-specific Variables:
# terraform.tfvars for dev aws_region = "us-east-1" cidr_block = "10.0.0.0/16" # terraform.tfvars for prod aws_region = "us-west-2" cidr_block = "10.1.0.0/16"
Now, you can have different sets of configurations for dev, prod, and test environments with environment-specific variables that can be managed with different workspaces.
Secure Secrets and Sensitive Data
Use Terraform variables with `sensitive = true` and AWS Secrets Manager.
Example (variables.tf):
variable "db_password" { description = "Database password" type = string sensitive = true }
Essential Terraform Commands
These commands are used in most Terraform workflows.
Initialization:
terraform init
Plan the deployment:
terraform plan -var="aws_region=us-east-1"
Apply changes:
terraform apply -var="aws_region=us-east-1" -auto-approve
Check Terraform state:
terraform state list
Destroy resources:
terraform destroy -var="aws_region=us-east-1" -auto-approve
Deploying an AWS VPC
This example provisions a VPC with public and private subnets.
VPC Module (vpc.tf):
module "vpc" { source = "./modules/vpc" vpc_name = "prod-vpc" cidr_block = "10.0.0.0/16" public_subnets = ["10.0.1.0/24", "10.0.2.0/24"] private_subnets = ["10.0.3.0/24", "10.0.4.0/24"] }
VPC Module (modules/vpc/main.tf):
resource "aws_vpc" "main" { cidr_block = var.cidr_block tags = { Name = var.vpc_name } }
Variables (modules/vpc/variables.tf):
variable "vpc_name" { type = string } variable "cidr_block" { type = string } variable "public_subnets" { type = list(string) } variable "private_subnets" { type = list(string) }
Deploying a Terraform CI/CD Pipeline
A Terraform CI/CD pipeline ensures consistent and automated deployments. This example uses AWS CodePipeline.
Pipeline Stages:
- Source – Fetch Terraform code from Bitbucket.
- Plan – Run `terraform plan`.
- Approve – Manual approval for `prod`.
- Apply – Run `terraform apply`.
Pipeline Definition (pipeline.tf):
resource "aws_codepipeline" "terraform_pipeline" { name = "terraform-deploy" role_arn = aws_iam_role.pipeline_role.arn artifact_store { location = "my-codepipeline-bucket" type = "S3" } stage { name = "Source" action { name = "FetchSource" category = "Source" owner = "AWS" provider = "CodeCommit" version = "1" configuration = { RepositoryName = "terraform-repo", BranchName = "main" } output_artifacts = ["source_output"] } } stage { name = "Plan" action { name = "TerraformPlan" category = "Build" owner = "AWS" provider = "CodeBuild" version = "1" input_artifacts = ["source_output"] configuration = { ProjectName = aws_codebuild_project.terraform_plan.name } } } stage { name = "Approve" action { name = "ManualApproval" category = "Approval" owner = "AWS" provider = "Manual" version = "1" } } stage { name = "Apply" action { name = "TerraformApply" category = "Build" owner = "AWS" provider = "CodeBuild" version = "1" input_artifacts = ["source_output"] configuration = { ProjectName = aws_codebuild_project.terraform_apply.name } } } }
Security Best Practices
- Enable AWS Config & GuardDuty – Monitor changes and security threats.
- Encrypt sensitive data – Use AWS KMS for encrypting resources.
- Use private subnets – Keep sensitive resources off the public internet.
- Use IAM roles with least privilege access.
Conclusion
By following these Terraform best practices for AWS, you ensure a secure, scalable, and efficient infrastructure. Keep your Terraform setup modular, automated, and well-documented.
Deploying with Workspaces for Environment Separation
Workspaces are useful when you want to maintain environment separation in a single Terraform configuration. For example, each environment (dev, test, prod) would have its own workspace, ensuring separate state files and variable configurations.
Steps to Deploy Using Workspaces: 1. Create and switch to a workspace:
terraform workspace new dev terraform workspace select dev terraform apply
2. Apply changes in the dev environment:
terraform apply
3. Switch to the production workspace and apply:
terraform workspace select prod terraform apply
By using workspaces, you separate your environments' state files, making it easier to manage infrastructure across multiple environments. Each workspace can have different configurations or even different variables.
Deploying Without Workspaces
If you don't want to use workspaces and want to deploy in different environments without this separation, you can use distinct `terraform.tfvars` files or specify variables directly in the command line.
For example: 1. In the dev environment, you could specify variables like so:
terraform apply -var="aws_region=us-east-1" -var="cidr_block=10.0.0.0/16"
2. For production, you can specify a different set of variables:
terraform apply -var="aws_region=us-west-2" -var="cidr_block=10.1.0.0/16"
This method doesn’t use workspaces but still allows different configurations for different environments by passing the relevant variables during the apply phase.
---
Retrieved from your Terraform Wiki