1. Conditionals
Terraform supports conditional expressions, which enable you to make decisions in your configurations. For example:
variable "environment" {
default = "prod"
}
resource "aws_instance" "example" {
instance_type = var.environment == "prod" ? "t2.large" : "t2.micro"
}
-
Syntax:
condition ? true_value : false_value
-
Use case: Dynamically assign values based on conditions (e.g., production vs. development environments).
2. Loops
Terraform provides constructs to iterate over collections like lists and maps.
For Expressions
- Used to transform data structures (lists/maps).
variable "names" {
default = ["alice", "bob", "charlie"]
}
output "formatted_names" {
value = [for name in var.names : upper(name)]
}
- Syntax:
[for item in collection : expression]
Count Argument
- Used to create multiple resources of the same type.
resource "aws_instance" "example" {
count = 3
instance_type = "t2.micro"
}
count.index
: Refers to the index of each created instance.
For-Each Argument
- Used for iterating over maps or sets.
resource "aws_s3_bucket" "example" {
for_each = { bucket1 = "A", bucket2 = "B" }
bucket = each.key
tags = { Name = each.value }
}
3. Built-in Functions
Terraform includes a wide array of functions for string manipulation, math, collections, and more:
-
String functions:
upper()
,lower()
,join()
,split()
,trimspace()
-
Numeric functions:
max()
,min()
,ceil()
,floor()
-
Collection functions:
length()
,concat()
,lookup()
,merge()
-
Logical functions:
can()
(checks if an expression can be evaluated),coalesce()
,default()
-
Date functions:
timestamp()
,timeadd()
Example:
output "example" {
value = join(", ", ["one", "two", "three"])
}
4. Logical Operators
Terraform supports logical operators for complex conditions:
-
AND:
&&
-
OR:
||
-
NOT:
!
Example:
variable "enabled" {
default = true
}
output "should_provision" {
value = var.enabled && true
}
5. Dynamic Blocks
Dynamic blocks allow conditional or loop-based resource definitions within a block:
resource "aws_security_group" "example" {
dynamic "ingress" {
for_each = var.ingress_rules
content {
from_port = ingress.value.from_port
to_port = ingress.value.to_port
protocol = ingress.value.protocol
cidr_blocks = ingress.value.cidr_blocks
}
}
}
6. Terraform Variables
You can use variables to manage configurations dynamically:
-
Input variables: Pass values into a configuration.
-
Output variables: Display results after
terraform apply
.
Example:
variable "instance_type" {
default = "t2.micro"
}
resource "aws_instance" "example" {
instance_type = var.instance_type
}
7. Modules
Modules are a way to group and reuse Terraform configuration. You can think of them as reusable components or building blocks of your infrastructure.
-
How Logic Fits: Modules allow you to encapsulate and manage logic for specific infrastructure components (e.g., VPC, EC2, etc.), and they can be parameterized with variables.
-
Example:
module "vpc" { source = "./modules/vpc" cidr_block = "10.0.0.0/16" environment = var.environment }
By leveraging modules, you can implement logic in a more modular way, making your configurations cleaner and easier to manage.
8. Resource Dependencies
Terraform automatically understands dependencies between resources. However, sometimes you may need to explicitly define dependencies using the depends_on
argument.
-
Example:
resource "aws_instance" "example" { ami = "ami-123456" instance_type = "t2.micro" depends_on = [aws_s3_bucket.example] }
This ensures that the EC2 instance is only created after the specified S3 bucket exists.
9. Data Sources
Data sources are used to query information from external systems, which can be used as input for your infrastructure.
-
How It Adds Logic: You can dynamically fetch data, like AMIs or VPC IDs, instead of hardcoding them.
-
Example:
data "aws_ami" "latest" { most_recent = true owners = ["self"] } resource "aws_instance" "example" { ami = data.aws_ami.latest.id instance_type = "t2.micro" }
10. Outputs
Outputs allow you to extract and share information about your infrastructure after terraform apply
.
-
Example:
output "instance_id" { value = aws_instance.example.id }
These outputs can be used for debugging or chaining workflows when multiple Terraform configurations are used together.
11. State Manipulation Logic
Terraform uses a state file to manage infrastructure. State manipulation logic includes commands like importing resources, refreshing state, and managing remote state backends.
-
Commands Related to State:
-
terraform import
: Import existing infrastructure into Terraform. -
terraform state list
: List resources in the state file. -
terraform state rm
: Remove a resource from the state file. -
terraform refresh
: Sync state with real-world infrastructure.
-
12. Dynamic Variables with Maps
You can use maps to dynamically assign values for variables or configurations.
-
Example:
variable "instance_types" { default = { dev = "t2.micro" prod = "t2.large" } } resource "aws_instance" "example" { instance_type = var.instance_types[var.environment] }
13. Expressions for Advanced Logic
Terraform supports complex expressions to compute values dynamically:
-
Using
lookup
for default values:variable "tags" { default = {} } resource "aws_s3_bucket" "example" { tags = merge(var.tags, { Name = "default-bucket-name" }) }
-
Using
coalesce
for fallback values:resource "aws_s3_bucket" "example" { bucket = coalesce(var.bucket_name, "default-bucket") }
14. File and Template Functions
Terraform allows reading files and rendering templates with logic:
-
Read a file:
data "template_file" "config" { template = file("${path.module}/config.tpl") }
15. Error Handling and Validation
You can define validation rules for variables and use error functions for better control.
-
Variable Validation:
variable "instance_type" { type = string validation { condition = contains(["t2.micro", "t2.large"], var.instance_type) error_message = "Instance type must be 't2.micro' or 't2.large'." } }
-
Custom Error Messages:
locals { valid = var.environment == "prod" || var.environment == "dev" } resource "aws_instance" "example" { ami = "ami-123456" instance_type = "t2.micro" count = local.valid ? 1 : error("Environment must be 'prod' or 'dev'") }
16. Workspaces
Terraform workspaces are used for managing multiple environments (e.g., dev
, staging
, prod
) within a single configuration.
-
Default Behavior: Every Terraform configuration has a default workspace called
default
. -
Custom Workspaces:
terraform workspace new dev terraform workspace select dev terraform workspace show
-
terraform.workspace
can be used in your configurations to adjust behavior:resource "aws_instance" "example" { instance_type = terraform.workspace == "prod" ? "t2.large" : "t2.micro" }
-
This helps isolate resources per environment without duplicating configuration files.
17. Terraform Backends
Backends allow you to store Terraform state remotely, enabling team collaboration and state locking to prevent conflicts. You can add logic in your configuration to specify backends dynamically or securely.
-
Example for S3 Backend:
terraform { backend "s3" { bucket = "my-terraform-state" key = "${terraform.workspace}/terraform.tfstate" region = "us-east-1" dynamodb_table = "terraform-locks" } }
This setup uses the workspace name in the state file path for isolation.
18. Handling Sensitive Data
Terraform allows you to manage sensitive data such as passwords and API keys. By default, sensitive values are masked in outputs.
-
Mark Variables as Sensitive:
variable "db_password" { type = string sensitive = true }
-
Prevent Sensitive Output:
output "password" { value = var.db_password sensitive = true }
If sensitive variables are accidentally hardcoded, tools like HashiCorp Vault or cloud provider key management systems (KMS) can secure them.
19. File Interpolation
Terraform can read file contents or templates and use them in your configurations.
-
Using
file()
to Read Content:resource "aws_instance" "example" { user_data = file("init_script.sh") }
-
Using
templatefile()
for Dynamic Templates:resource "aws_instance" "example" { user_data = templatefile("${path.module}/user_data.tpl", { hostname = "example" }) }
This allows dynamic rendering and reuse of configurations.
20. Provider Logic
Providers allow you to manage resources for specific platforms (e.g., AWS, Azure, Google Cloud). You can use multiple providers with logic to target different regions or accounts.
-
Example:
provider "aws" { region = var.environment == "prod" ? "us-east-1" : "us-west-2" }
21. Advanced Dependency Management
You can define explicit dependencies between resources to ensure proper sequencing, even when dependencies are implicit.
-
Example with
depends_on
:resource "aws_db_instance" "db" { # Configuration here } resource "aws_lambda_function" "lambda" { depends_on = [aws_db_instance.db] }
This ensures the database is created before the Lambda function.
22. Dynamic Variables with locals
locals
can be used to calculate intermediate values or reduce repetition in configurations.
-
Example:
locals { instance_type = var.environment == "prod" ? "t2.large" : "t2.micro" tags = { Environment = var.environment Team = "DevOps" } } resource "aws_instance" "example" { instance_type = local.instance_type tags = local.tags }
23. Error Handling with try()
The try()
function lets you handle situations where an expression might fail. It attempts multiple expressions in order until one succeeds.
-
Example:
resource "aws_instance" "example" { ami = try(data.aws_ami.latest.id, "ami-default") }
If data.aws
_
ami.latest.id
is invalid or missing, the fallback value "ami-default"
will be used.
24. Custom Modules with Logic
Custom modules can encapsulate reusable logic and provide parameters for flexibility. For example:
Module Structure:
modules/
vpc/
main.tf
variables.tf
outputs.tf
Example Usage:
module "vpc" {
source = "./modules/vpc"
cidr_block = "10.0.0.0/16"
environment = var.environment
}
Modules allow you to write once and reuse across multiple configurations.
25. Handling Complex Maps and Lists
Terraform allows you to work with complex data structures like nested maps and lists. You can dynamically loop through them or extract specific values.
-
Example with Nested Maps:
variable "team_info" { default = { dev = { name = "Alice", age = 25 } prod = { name = "Bob", age = 30 } } } output "team_names" { value = [for env, info in var.team_info : info.name] }
In this example, the loop extracts name
values (Alice
, Bob
) from the nested map.
26. Using Terraform Data Structures for Dependency Management
Complex dependencies can be managed by combining data sources and outputs, often used to dynamically link resources across modules or configurations.
-
Example with Cross-Module Outputs:
module "vpc" { source = "./modules/vpc" cidr_block = "10.0.0.0/16" } resource "aws_instance" "example" { subnet_id = module.vpc.public_subnet_id }
Here, the aws_instance
resource dynamically uses the output of the vpc
module for provisioning.
27. Use of null
for Conditional Logic
Terraform supports the null
keyword for conditional logic. It acts as a placeholder when you want to ignore or skip certain configurations.
-
Example:
resource "aws_ebs_volume" "example" { count = var.attach_volume ? 1 : 0 size = var.volume_size type = var.volume_type } resource "aws_volume_attachment" "attach" { count = var.attach_volume ? 1 : 0 volume_id = aws_ebs_volume.example.id instance_id = var.instance_id }
Here, the resources are conditionally provisioned based on the value of var.attach_volume
.
28. Advanced Debugging with terraform console
Terraform provides a debugging console where you can test and evaluate expressions. This helps with troubleshooting and validating logic before deployment.
-
Usage:
terraform console > var.environment == "prod" ? "Production Environment" : "Development Environment" > join(", ", ["Alice", "Bob", "Charlie"])
29. Chaining Modules for Complex Architectures
You can use modules together to build complex, interconnected architectures dynamically.
-
Example:
module "network" { source = "./modules/network" cidr_block = "10.0.0.0/16" } module "compute" { source = "./modules/compute" subnet_ids = module.network.subnet_ids instance_count = var.instance_count }
Here, the output of one module feeds into another module, enabling flexible and scalable designs.
30. Working with State Outputs
Terraform state allows you to query and use outputs directly from remote configurations.
-
Example with
terraform_remote_state
:data "terraform_remote_state" "network" { backend = "s3" config = { bucket = "my-state-bucket" key = "network/terraform.tfstate" region = "us-east-1" } } resource "aws_instance" "example" { subnet_id = data.terraform_remote_state.network.outputs.subnet_id }
31. Terraform Workspace-Specific Logic
You can use workspaces to customize configurations based on the environment (e.g., dev
, prod
).
-
Example:
resource "aws_s3_bucket" "example" { bucket = terraform.workspace == "prod" ? "prod-bucket" : "dev-bucket" }
32. Integration with CI/CD
Terraform can be integrated into CI/CD pipelines for automated infrastructure provisioning. Logic for variables and modules can be used dynamically based on pipeline conditions.
-
Example:
steps: - name: Terraform Init run: terraform init - name: Terraform Plan run: terraform plan -var="environment=prod" - name: Terraform Apply run: terraform apply -auto-approve
This ensures configurations are applied automatically in response to changes in code.
33. Custom Backends with Logic
Backends are not limited to S3
; they can be dynamically configured using variables for reusability across different environments.
-
Example of Dynamic Backend Setup:
terraform { backend "s3" { bucket = var.backend_bucket key = "${var.environment}/terraform.tfstate" region = var.backend_region dynamodb_table = var.backend_table } }
This allows flexibility to configure backends dynamically using variable input during runtime.
34. Local-Exec and Remote-Exec Provisioners
Provisioners allow you to run scripts and commands as part of the resource creation process. These are useful for custom initialization or post-deployment tasks.
Local-Exec Provisioner:
Runs commands on the machine where Terraform is running.
resource "aws_instance" "example" {
provisioner "local-exec" {
command = "echo 'Instance created!'"
}
}
Remote-Exec Provisioner:
Runs commands on the target resource after it is created.
resource "aws_instance" "example" {
provisioner "remote-exec" {
inline = [
"sudo apt-get update",
"sudo apt-get install -y nginx"
]
}
}
Provisioners should generally be used as a last resort, but they’re powerful when needed.
35. Sentinel Policies for Policy-As-Code
Sentinel is a policy-as-code framework integrated into Terraform Enterprise for governance. It allows you to enforce policies to ensure compliance and security.
-
Example Sentinel Policy:
main = rule { all resources.aws_instance as _, instance { instance.instance_type matches "t2.*" } }
This policy ensures only certain instance types (t2.micro
, t2.large
, etc.) are used in configurations.
36. Using External Data Sources
The external
data source allows Terraform to integrate with external systems by running external programs/scripts.
-
Example with an External Script:
data "external" "example" { program = ["python", "${path.module}/script.py"] query = { key = "value" } } output "external_data" { value = data.external.example.result }
This is useful for dynamic configurations where data comes from external APIs, scripts, or other services.
37. Managing State Across Environments
When dealing with multiple environments (like dev
, staging
, prod
), you can dynamically manage and isolate state files using workspaces and remote backends.
-
Example:
terraform workspace new staging terraform workspace select staging terraform apply
-
Combine it with dynamic state management logic:
terraform { backend "s3" { key = "${terraform.workspace}/terraform.tfstate" } }
This isolates the state file for each environment.
38. Variable Default Values with Logic
You can use logical expressions to set default values for variables, making your configurations adaptable.
-
Example with Fallback Logic:
variable "region" { default = can(env("AWS_REGION")) ? env("AWS_REGION") : "us-east-1" }
Here, the region
defaults to the environment variable AWS_REGION
if it exists; otherwise, it falls back to "us-east-1"
.
39. Combining Terraform with Automation Tools
You can integrate Terraform with tools like Ansible, Chef, or Puppet to handle provisioning beyond infrastructure.
-
Example Terraform Output for Ansible:
output "ansible_inventory" { value = join("\n", aws_instance.example.*.public_ip) }
This generates an inventory file that can be consumed by Ansible for further configuration management.
40. Dynamic Nested Blocks
Dynamic blocks allow you to generate complex nested configurations programmatically.
-
Example:
resource "aws_security_group" "example" { dynamic "ingress" { for_each = var.ingress_rules content { from_port = ingress.value.from_port to_port = ingress.value.to_port protocol = ingress.value.protocol cidr_blocks = ingress.value.cidr_blocks } } }
This creates ingress
blocks for each rule in var.ingress_rules
.
41. Managing Costs and Tags
You can implement tagging best practices for resources to help with cost management and organization.
-
Example:
variable "default_tags" { default = { Team = "DevOps" Environment = var.environment } } resource "aws_instance" "example" { tags = merge(var.default_tags, { Name = "my-instance" }) }
This ensures consistent tagging across all resources.
42. Terraform Integration with GitOps
Incorporating Terraform into a GitOps workflow allows automated infrastructure provisioning based on repository changes.
-
Example Workflow:
-
Push changes to a Git repository.
-
A CI/CD tool (like Jenkins or GitHub Actions) runs:
terraform init terraform plan terraform apply -auto-approve
-
This automates infrastructure deployment directly from version control.
43. Custom Terraform Providers
You can create custom providers to manage resources or systems not supported by the default Terraform providers.
- Example: Use the Terraform Provider Development Guide to create a Go-based provider for your custom resource.
44. Pre-Apply Validation
You can use a combination of variables, conditions, and validation rules to ensure configurations are valid before applying.
-
Example:
variable "instance_count" { type = number validation { condition = var.instance_count > 0 error_message = "Instance count must be greater than 0" } }
This prevents invalid input during execution.
45. Integration with Secrets Management
Terraform integrates with secrets management tools to securely handle sensitive data like API keys, passwords, and certificates.
-
Example with HashiCorp Vault:
data "vault_generic_secret" "example" { path = "secret/data/db_password" } output "db_password" { value = data.vault_generic_secret.example.data["password"] }
-
Other Integrations: Terraform can pull secrets from AWS Secrets Manager, Azure Key Vault, or GCP Secret Manager using dedicated providers.
46. Conditional Modules
Terraform allows you to conditionally include or exclude modules.
-
Example:
module "optional_module" { source = "./modules/optional" count = var.use_optional_module ? 1 : 0 }
This ensures the module is only instantiated if var.use_optional_module
is true
.
47. Terraform Graph
The terraform graph
command generates a visual representation of the dependency tree in your configuration. You can use this to debug dependencies or understand the relationships between resources.
-
Command:
terraform graph | dot -Tsvg > graph.svg
This generates an SVG file of the resource dependency graph, which you can open in any web browser.
48. Error Handling with Custom Exceptions
Although Terraform does not natively support exceptions, you can emulate error handling using custom expressions and variables.
-
Example:
resource "aws_instance" "example" { count = var.valid ? 1 : error("The configuration is invalid!") }
This stops the deployment if certain conditions are not met.
49. Terraform Module Versioning
Terraform modules in the registry can be versioned for better control and stability.
-
Example:
module "vpc" { source = "terraform-aws-modules/vpc/aws" version = "~> 3.5" }
The ~>
syntax ensures compatibility with versions within the range (e.g., 3.5.x
).
50. Provider Aliases
Terraform allows you to use provider aliases for deploying resources across multiple regions or accounts.
-
Example:
provider "aws" { alias = "us-east" region = "us-east-1" } provider "aws" { alias = "us-west" region = "us-west-2" } resource "aws_instance" "east_instance" { provider = aws.us-east ami = "ami-123456" instance_type = "t2.micro" } resource "aws_instance" "west_instance" { provider = aws.us-west ami = "ami-789012" instance_type = "t2.micro" }
51. Multi-Cloud Deployments
Terraform makes deploying infrastructure across multiple clouds seamless by using separate providers.
-
Example:
resource "aws_instance" "example" { provider = aws instance_type = "t2.micro" ami = "ami-123456" } resource "azurerm_virtual_machine" "example" { provider = azurerm vm_size = "Standard_DS1_v2" name = "example-vm" location = "East US" }
This allows you to manage resources on AWS and Azure in the same configuration.
52. Validate Custom Modules Locally
Before publishing a module to the Terraform Registry or sharing it, validate it locally to ensure consistency.
-
Command:
terraform validate
This checks the configuration syntax for issues.
53. timeadd
and Temporal Logic
Terraform supports temporal logic for tasks like scheduling resource expiration or dynamically calculating future dates.
-
Example:
resource "aws_iam_role" "example" { max_session_duration = timeadd(timestamp(), "3600") }
This sets the session duration to one hour from the current time.
54. Cross-Region Replication
Terraform configurations can be written to handle cross-region replication for disaster recovery purposes.
-
Example:
resource "aws_s3_bucket_replication_configuration" "example" { role = aws_iam_role.replication_role.arn rules { id = "ReplicationRule" destination { bucket = aws_s3_bucket.destination_bucket.arn region = "us-west-2" } } }
55. Managing State Drift
Terraform can identify differences between your configuration and actual infrastructure using terraform plan
.
-
Command:
terraform plan -refresh-only
This refreshes the state and reports any drift.
56. Remote Module Calls
Modules can be sourced directly from Git repositories or remote registries.
-
Example:
module "network" { source = "git::https://github.com/user/repo.git//network" }
This enables dynamic reuse of modules stored remotely.
57. terragrunt
for Hierarchical Configurations
Terragrunt is a wrapper for Terraform that helps with managing configurations across environments or hierarchical setups.
-
Example:
terragrunt apply --terragrunt-config ./prod/terragrunt.hcl
This allows you to simplify multi-environment setups.
58. Using Terraform with Event-Driven Infrastructure
Terraform can be integrated with tools like AWS EventBridge or Azure Event Grid to create event-driven architectures. This involves provisioning resources to respond to specific events.
-
Example with AWS EventBridge:
resource "aws_cloudwatch_event_rule" "example" { name = "event-rule" description = "Trigger on EC2 instance state changes" event_pattern = <<PATTERN { "source": ["aws.ec2"], "detail-type": ["EC2 Instance State-change Notification"] } PATTERN } resource "aws_lambda_function" "example" { runtime = "python3.8" handler = "handler.lambda_handler" source_code_hash = filebase64sha256("function.zip") environment { variables = { EVENT_SOURCE = "aws.ec2" } } }
This sets up a Lambda function that reacts to EC2 state-change notifications.
59. Managing Blue-Green Deployments
You can use Terraform to implement Blue-Green deployment strategies for safer updates to your infrastructure, reducing downtime during rollouts.
-
Example with AWS ALB:
resource "aws_lb_target_group" "blue" { name = "blue-target-group" port = 80 protocol = "HTTP" vpc_id = var.vpc_id } resource "aws_lb_target_group" "green" { name = "green-target-group" port = 80 protocol = "HTTP" vpc_id = var.vpc_id } resource "aws_lb_listener_rule" "blue-green" { listener_arn = aws_lb_listener.example.arn conditions { field = "host-header" values = ["blue.myapp.com"] } actions { type = "forward" target_group_arn = aws_lb_target_group.blue.arn } }
By swapping traffic between blue
and green
target groups, you achieve zero-downtime deployments.
60. Using dynamic
Block for Complex Logic
Terraform’s dynamic
block enables powerful configurations for repeating nested blocks with variable inputs.
-
Example for Dynamic Tags:
resource "aws_instance" "example" { ami = "ami-123456" instance_type = "t2.micro" dynamic "tags" { for_each = var.tags content { key = tags.key value = tags.value } } }
This dynamically generates tags based on the input map var.tags
.
61. Multiple State Files
When working on large infrastructure projects, splitting state files by module or environment can improve management.
-
Example with Remote State:
terraform { backend "s3" { bucket = "terraform-state" key = "${var.project_name}/terraform.tfstate" } }
By using different keys, you can isolate state files for modules or environments.
62. Resource Lifecycle Management
Terraform has lifecycle hooks to control the creation, update, or destruction of resources.
-
Example:
resource "aws_instance" "example" { ami = "ami-123456" instance_type = "t2.micro" lifecycle { create_before_destroy = true prevent_destroy = true } }
-
create_before_destroy
: Ensures a new resource is created before the old one is destroyed. -
prevent_destroy
: Prevents accidental destruction of critical resources.
63. Automated Drift Detection
Terraform can detect drift (differences between your configuration and real-world infrastructure) using external tools like terraform plan
combined with alerts.
-
Example Integration with CI/CD:
terraform plan -detailed-exitcode if [[ $? -eq 2 ]]; then echo "Drift detected. Please investigate." fi
This automates drift detection in pipelines.
64. Infrastructure Testing with Terraform
Integrate testing frameworks like Terratest
to validate your Terraform configurations. You can write tests to ensure resources are created as expected.
-
Example Test in Go:
func TestTerraformModule(t *testing.T) { options := &terraform.Options{ TerraformDir: "./example", } terraform.InitAndApply(t, options) output := terraform.Output(t, options, "instance_id") assert.NotNil(t, output) }
65. Custom Resource Deletion Logic
Terraform allows you to write logic for specific deletion scenarios.
-
Example using Conditional Resource Deletion:
resource "aws_instance" "example" { count = var.delete_instance ? 0 : 1 ami = "ami-123456" }
Here, delete_instance
controls whether the EC2 instance is removed.
66. Encrypting State Files
Always encrypt your state files to secure sensitive information. Terraform supports encrypted state files with remote backends like AWS S3.
-
Example with Encryption:
terraform { backend "s3" { bucket = "my-state-bucket" key = "state/terraform.tfstate" encrypt = true kms_key_id = "alias/terraform-key" } }
This ensures state files are encrypted at rest.
67. Conditional Outputs
Outputs in Terraform can be conditionally displayed based on runtime variables.
-
Example:
output "private_key" { value = var.show_key ? var.key : null sensitive = true }
This ensures that sensitive outputs are only shown when explicitly needed.
68. Terraform Provider Debugging
Enable debugging for providers to troubleshoot issues during resource creation.
-
Command:
TF_LOG=DEBUG terraform apply
This provides detailed logs of operations performed by Terraform.
69. Modular Resource Groups
You can use dynamic groups of resources in modules for improved flexibility.
-
Example:
module "compute_group" { source = "./modules/compute" instance_type = var.instance_type instance_count = var.instance_count }
This dynamically creates groups of compute instances.