Terraform
Workspace based terraform automation project setup for multi-cloud.
Cloud Module Referenceβ
Folder structure of terrafrom projectβ
TERRAFORM
β .gitignore
β .terraform.lock.hcl
β main.tf # Main terraform file
β outputs.tf # Output variables
β provider.tf # All providers with version number declaration
β terrafrom.tfvars # Terraform's default variables definitions.
β variables.tf # Terraform variables declarations
β
ββββ.terraform
β β environment
β β
β ββββmodules
β β modules.json
β β
β ββββproviders
β ββββregistry.terraform.io
β
ββββterraform.tfstate.d
ββββTest
ββββUat
ββββProd
Note:
terrafrom.tfvars
is default variable definition file. Custom name is acceptable. but need to spacify the file name in every execution liekterraform apply var-file=test.env.tfvars
Init the terraform projectβ
terraform init (or) terraform init --upgrade
Terrafrom workspaceβ
# Create workspace
terrafrom workspace new Test
terrafrom workspace new Uat
terrafrom workspace new Prod
# Select/Change workspace
terraform workspace select Test
# List all workspace
terraform workspace list
# Deelte workspace
terraform workspace delete Test
Planβ
terraform plan # terraform will take terraform.tfvars as default variable file.
terraform plan var-file=test.evn.tfvars
Applyβ
terraform apply -y var-file=test.env.tfvars
Azureβ
Authenticaton setupβ
export ARM_SUBSCRIPTION_ID="<azure_subscription_id>"
export ARM_TENANT_ID="<azure_subscription_tenant_id>"
export ARM_CLIENT_ID="<service_principal_appid>"
export ARM_CLIENT_SECRET="<service_principal_password>"
Note: When authenticating as a Service Principal using a Client Secret,
client_secret
fields need to be set. This can also be sourced from the ARM_CLIENT_SECRET Environment Variable.
(or)
provider "azurerm" {
subscription_id = var.azure.subscription_id
# client_id = var.azure.client_id
# client_secret = var.azure.client_secret
tenant_id = var.azure.tenant_id
features {}
}
Secure State file in Azure Storeageβ
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "=2.46.0"
}
}
backend "azurerm" {
resource_group_name = "tfstate"
storage_account_name = "<storage_account_name>"
container_name = "tfstate"
key = "terraform.tfstate"
}
}
AWSβ
Authenticaton Setupβ
export AWS_ACCESS_KEY_ID="anaccesskey"
export AWS_SECRET_ACCESS_KEY="asecretkey"
export AWS_DEFAULT_REGION="us-west-2"
terraform plan
Secure state file in AWS S3 Bucketβ
terraform {
backend "s3" {
bucket = "mybucket"
key = "path/to/my/key"
region = "us-east-1"
}
}
Reference
GCPβ
Authenticaton setupβ
Secure state file in GCS (Google Cloud Storage)β
terraform {
backend "gcs" {
bucket = "tf-state-prod"
prefix = "terraform/state"
}
}
Reference
Sample terraform scriptsβ
Multi cloud terrafrom project
provider.tf
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.2"
}
azurerm = {
source = "hashicorp/azurerm"
version = "2.98.0"
}
google = {
version = "~> 3.8"
}
random = "~> 2.2"
docker = "~> 2.7"
}
backend "azurerm" {
resource_group_name = "tfstate"
storage_account_name = "<storage_account_name>"
container_name = "tfstate"
key = "terraform.tfstate"
}
}
provider "aws" {
profile = var.aws.profile
region = var.aws.region
access_key = var.aws.access_key
secret_key = var.aws.secret_key
}
provider "azurerm" {
subscription_id = var.azure.subscription_id
# client_id = var.azure.client_id
# client_secret = var.azure.client_secret
tenant_id = var.azure.tenant_id
features {}
}
provider "google" {
credentials = file("account.json")
project = var.gcp.project_id
region = var.gcp.region
}
provider "docker" {
}
terraform.tfvars
aws = {
profile = "default" # ENV = AWS_PROFILE
region = "us-west-2" # ENV = AWS_REGION
access_key = "xxxxxxxxxxxxxxxxxxx" # ENV = AWS_ACCESS_KEY_ID
secret_key = "xxxxxxxxxxxxxxxxxxx" # ENV= AWS_SECRET_ACCESS_KEY
}
azure = {
subscription_id = "xxxx-xxxxx-xxxxx-xxxxx-xxxx-xxxx" # ENV = ARM_SUBSCRIPTION_ID
# client_id = "xxxx-xxxxx-xxxxx-xxxxx-xxxx-xxxx" # ENV = ARM_CLIENT_ID
# client_secret = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx" # ENV= ARM_CLIENT_SECRET
tenant_id = "xxxx-xxxxx-xxxxx-xxxxx-xxxx-xxxx" # ENV = ARM_TENANT_ID
location = "centralus"
}
gcp = {
project_id = "<project_id>"
region = "us-east1"
}
variables.tf
variable "aws" {
type = object({
profile = string
region = string
access_key = string
secret_key = string
})
}
variable "azure" {
type = object({
subscription_id = string
# client_id = string
# client_secret = string
tenant_id = string
location = string
})
}
variable "gcp" {
type = object({
project_id = string
region = string
})
}
output.tf
output "addresses" {
value = {
# aws = module.aws.network_address
# azure = module.azure.network_address
# gcp = module.gcp.network_address
# loadbalancer = module.loadbalancer.network_address
}
}