1. Dynamic Context with Data Sources & Locals
Hardcoding AWS Account IDs or Region names creates fragile configurations. By leveraging AWS Data Sources, infrastructure context is queried live during runtime and fed directly into centralized local tag blocks.
# data.tf
data "aws_caller_identity" "current" {}
data "aws_region" "current" {}
# locals.tf
locals {
common_tags = {
Environment = var.environment
ManagedBy = "Terraform"
CreatedBy = "Alain Puron"
Region = data.aws_region.current.region
AccountId = data.aws_caller_identity.current.account_id
}
}
2. DRY Resource Generation with `for_each`
Rather than duplicating resource blocks for every CloudWatch Log Group, a single dynamic block driven by a string set variable processes multiple Lambda functions cleanly while maintaining individual state tracking.
# logging.tf
resource "aws_cloudwatch_log_group" "lambda_logs" {
for_each = var.lambda_functions
name = "/aws/lambda/${each.value}"
retention_in_days = var.log_retention_days
tags = local.common_tags
}
3. Feature Flagging with Conditional Toggles
To control resource creation across environments without altering code structure, conditional evaluation (`count`) is paired with boolean flag variables.
# alarms.tf
resource "aws_cloudwatch_metric_alarm" "visitor_lambda_errors" {
count = var.enable_alerts ? 1 : 0
alarm_name = "visitor-lambda-error-alarm"
comparison_operator = "GreaterThanThreshold"
evaluation_periods = 1
metric_name = "Errors"
namespace = "AWS/Lambda"
period = 300
statistic = "Sum"
threshold = 1
dimensions = { FunctionName = "increment-visitor-counter" }
tags = local.common_tags
}
4. Adopting Existing AWS Resources via Declarative Imports
When AWS services auto-generate implicit resources (such as
Lambda creating log groups upon first execution), standard
deployments fail with a
ResourceAlreadyExistsException. Using native HCL
import blocks avoids complex CLI shell-escaping and
safely adopts unmanaged resources into state.
# imports.tf
import {
to = aws_cloudwatch_log_group.lambda_logs["increment-visitor-counter"]
id = "/aws/lambda/increment-visitor-counter"
}
import {
to = aws_cloudwatch_log_group.lambda_logs["send-contact-email"]
id = "/aws/lambda/send-contact-email"
}
5. Key Technical Takeaways
- Dynamic Output Mapping: Used dynamic `for` expressions in outputs (`[for lg in aws_cloudwatch_log_group.lambda_logs : lg.arn]`) to extract attributes across iterated resource collections.
- State Collision Resolution: Solved state conflicts declaratively directly in HCL code rather than relying on brittle CLI commands.
- Tag Standardization: Standardized resource tagging across the entire stack using `local.common_tags`.