An advanced, configuration-driven automation tool for creating Pull Requests across multiple Terraform repositories at scale, featuring intelligent parsing, comprehensive validation, enterprise-grade logging, and enhanced Slack integration with rich notifications.
This tool eliminates the manual, repetitive work involved in managing infrastructure changes across multiple Terraform repositories. Built with enterprise reliability in mind, it provides sophisticated parameter handling, comprehensive error reporting, rich Slack notifications with contextual information, and seamless integration with development workflows.
- Problem Statement
- Solution Overview
- Key Features
- Architecture
- Prerequisites
- Installation and Setup
- Testing and Validation
- Configuration Guide
- Advanced Features
- GitHub Actions Workflow
- Usage Examples
- Enhanced Slack Integration
- Success Metrics
- Logging and Monitoring
- Integration Options
- Best Practices
- Troubleshooting
- Known Limitations
- Benefits
- License
Organizations managing infrastructure with Terraform often face significant operational challenges:
- Scale Complexity: Managing hundreds of separate repositories across different environments, services, and teams
- Manual Overhead: Routine tasks like parameter updates, module version upgrades, and configuration changes require manual PR creation across many repositories
- Error-Prone Process: Manual copy-paste operations and human intervention increase the risk of inconsistencies and mistakes
- Time Consumption: Engineers spend valuable time on undifferentiated operational tasks instead of strategic work
- Coordination Burden: Keeping changes synchronized across repositories while maintaining proper documentation and traceability
- Visibility Gaps: Teams lack real-time visibility into infrastructure automation progress and results
Our automation tool transforms infrastructure management through a configuration-driven approach that:
- Eliminates Manual Work: Automates the entire workflow from configuration changes to PR creation
- Ensures Consistency: Applies identical changes across all targeted repositories with guaranteed consistency
- Provides Intelligence: Advanced HCL parsing handles complex nested Terraform structures automatically
- Offers Transparency: Comprehensive logging and validation provide full visibility into all operations
- Enhances Team Collaboration: Rich Slack notifications keep teams informed with contextual information and direct links
- Integrates Seamlessly: Optional integrations maintain existing workflow continuity while adding powerful automation
- Scales Effortlessly: Processes hundreds of repositories efficiently with built-in rate limiting and error handling
- Advanced HCL Parsing: Deep understanding of Terraform structure and syntax
- Nested Parameter Support: Handle complex parameter paths like
instance_market_options.spot_options.max_price - Safe Updates: Preserve comments, formatting, and structure integrity
- Automatic Formatting: Built-in
terraform fmtintegration
- Pre-flight Validation: Comprehensive configuration validation before execution
- Schema Enforcement: Strict validation of configuration file structure
- Type Safety: Parameter type checking and validation
- Clear Error Messages: Detailed, actionable error reporting with context
- Structured Logging: Multi-level logging with file output and console display
- Audit Trails: Complete operation history for compliance and debugging
- Progress Tracking: Real-time visibility into processing status
- Error Context: Detailed error information with full stack traces
- Rate Limiting: GitHub API rate limit awareness and automatic throttling
- Unique Branch Names: Collision-free branch naming with timestamp and repository context
- Error Recovery: Graceful handling of failures with automatic cleanup
- Change Detection: Intelligent detection of actual changes to prevent unnecessary operations
- Rich Slack Notifications: Beautiful, structured messages with contextual information
- Multiple Notification Types: Success notifications, error alerts, and batch processing summaries
- Contextual Information: Repository details, file counts, change summaries, and direct workflow links
- Customizable Appearance: Configurable bot username, emoji, and notification preferences
- Error Intelligence: Comprehensive error notifications with debugging information
- Configuration Engine: Validates and processes user-defined changes
- Repository Manager: Handles GitHub API interactions with rate limiting
- Terraform Processor: Advanced HCL parsing and intelligent parameter updates
- Change Detector: Identifies actual modifications to prevent unnecessary operations
- Enhanced Notification Hub: Manages rich Slack integration with contextual notifications
- Logging System: Comprehensive audit trail and monitoring
- Python 3.8+: Tested with Python 3.8 and above
- GitHub Personal Access Token: With
reposcope and organization access - Target Repositories: Must exist and be accessible with your token
- Terraform CLI: For formatting (optional but recommended)
- Visit: https://github.com/settings/tokens
- Generate new token (classic)
- Select scopes:
repo,workflow(if needed),read:org(for organization repos) - Copy token immediately (you won't see it again)
- Set environment variable:
export GITHUB_TOKEN="your_token"
- Target repositories must exist before running the tool
- Files specified in config.yaml must exist in the repositories
- GitHub token must have write access to create branches and PRs
| Secret Name | Description | Required | Notes |
|---|---|---|---|
GITHUB_TOKEN |
GitHub access token with repository permissions | β Yes | Must have repo scope |
SLACK_WEBHOOK_URL |
Slack webhook URL for enhanced notifications | β Optional | Can also be provided as workflow input |
Your GitHub token must have the following permissions:
repo- Full repository accessworkflow- Access to GitHub Actions (if modifying workflows)read:org- Organization access (for organization-owned repositories)
β οΈ Notice: This is sample code for non-production usage. You should work with your security and legal teams to meet your organizational security, regulatory and compliance requirements before deployment.
# Clone the automation tool repository
git clone https://github.com/aws-samples/sample-terraform-pr-automation-utility
cd sample-terraform-pr-automation-utility
# Copy example configuration
cp examples/config.example.yaml config.yaml# Install Python dependencies
pip3 install -r requirements.txt
# Verify installation
python3 -c "import github; import hcl2; import yaml; import requests; print('All packages installed successfully')"# Set GitHub token environment variable
export GITHUB_TOKEN="your_github_token_here"
# Verify token works
curl -H "Authorization: token $GITHUB_TOKEN" https://api.github.com/userEdit config.yaml to define your target repositories and desired changes:
repositories:
- owner: "your-org"
repo: "your-terraform-repo"
files:
- path: "variables.tf"
changes:
variables:
- app_version:
default:
update:
- from: ["1.0.0"]
to: "1.1.0"
settings:
pr_title_template: "Infrastructure Update - {{timestamp}}"
slack:
username: "Terraform Bot"
icon_emoji: ":terraform:"
notify_on_success: true
notify_on_error: true
notify_batch_summary: trueAlways test your configuration before running on production repositories:
# 1. Test configuration syntax
python3 -c "from main import get_config_content; get_config_content()"
# 2. Run in dry-run mode first
DRY_RUN=true python3 main.py
# 3. Test with minimal configuration
# Use a simple config.yaml with just one repository and one change# Test GitHub token access
curl -H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/owner/repo-name
# Should return repository information, not 404# Validate configuration structure
python3 -c "
from main import validate_config, get_config_content
try:
config = get_config_content()
validate_config(config)
print('β
Configuration validation successful')
except Exception as e:
print(f'β Configuration validation failed: {e}')
"repositories:
- owner: "github-org-name" # GitHub organization or username
repo: "repository-name" # Repository name
files: # List of files to modify
- path: "path/to/file.tf" # Terraform file path
changes: # Changes to apply
variables: [...] # Variable block changes
resources: [...] # Resource block changes
modules: [...] # Module block changes
settings: # Global settings
base_branch: "main" # Base branch for PRs
pr_title_template: "Update {{timestamp}}" # PR title template
create_pr: true # Whether to create PRs
# Enhanced Slack integration settings
slack:
username: "Terraform Bot" # Bot display name
icon_emoji: ":terraform:" # Bot emoji
notify_on_success: true # Success notifications
notify_on_error: true # Error notifications
notify_batch_summary: true # Batch summaries
include_changes_summary: true # Include change details
max_changes_displayed: 5 # Limit changes shownModify existing parameter values:
parameter_name:
update:
- from: ["old_value1", "old_value2"] # Values to match
to: "new_value" # New value to set
param_not_found:
action: skip # skip | add | error| Action | Behavior | Use Case |
|---|---|---|
skip |
Continue processing, log skip message | Optional parameters |
add |
Create parameter with specified value | Parameters that should exist |
error |
Stop processing with error | Critical required parameters |
resources:
- aws_instance.web:
# Simple parameter
instance_type:
update:
- from: ["t3.micro"]
to: "t3.small"
# Nested parameter
instance_market_options.spot_options.max_price:
update:
- from: ["0.003"]
to: "0.005"
param_not_found:
action: add
value: "0.005"
# Deeply nested parameter
root_block_device.ebs.volume_size:
update:
- from: ["20"]
to: "40"variables:
- kubernetes_version:
default:
update:
# Multiple from values in single rule
- from: ["1.27", "1.28", "1.29"]
to: "1.30"
# Additional rules for different scenarios
- from: ["1.25", "1.26"]
to: "1.29"
param_not_found:
action: error # Critical parameterThis configuration has been tested and verified to work (see config.yaml in the repository for a complete example):
repositories:
- owner: "your-github-username"
repo: "your-terraform-repo"
files:
- path: "variables.tf"
changes:
variables:
- kubernetes_version:
default:
update:
- from: ["1.27"]
to: "1.28"
param_not_found:
action: add
value: "1.28"
- vpc_cidr:
default:
update:
- from: ["10.0.0.0/16"]
to: "10.1.0.0/16"
param_not_found:
action: add
value: "10.1.0.0/16"
- path: "main.tf"
changes:
modules:
- vpc:
version:
update:
- from: ["5.7.0"]
to: "5.8.1"
param_not_found:
action: add
value: "5.8.1"
settings:
pr_title_template: "π§ Infrastructure Update - {{timestamp}}"
create_pr: truegit clone https://github.com/aws-samples/sample-terraform-pr-automation-utility
cd sample-terraform-pr-automation-utility
pip3 install -r requirements.txtexport GITHUB_TOKEN="your_github_token_here"# Validate config syntax
python3 -c "from main import get_config_content; get_config_content()"
# Test in dry-run mode
DRY_RUN=true python3 main.py# Run actual automation
python3 main.py- Check logs for processing status
- Review created pull requests
- Monitor Slack notifications (if configured)
When working correctly, you should see:
- β Configuration validation successful
- β All repositories processed: X/X successful
- β Pull Request created: https://github.com/owner/repo/pull/X
- β All files committed successfully
- β No critical errors in logs
INFO - Starting Terraform Infrastructure Update Automation
INFO - Configuration loaded successfully: 2 repositories
INFO - Processing repository 1/2: owner/repo
INFO - Created branch 'terraform-automation-repo-20250724-162703'
INFO - Successfully committed changes to variables.tf
INFO - β
Pull Request created: https://github.com/owner/repo/pull/9
INFO - β
All repositories processed successfully
The tool features sophisticated Terraform parsing capabilities:
Traditional Approach (Limited):
# Simple regex-based find and replace
content.replace('version = "1.0"', 'version = "1.1"')Our Advanced Approach:
# Intelligent HCL structure understanding
hcl_dict = hcl2.loads(terraform_content)
navigate_and_update_nested_structure(hcl_dict, parameter_path, new_value)
formatted_content = hcl2.dumps(hcl_dict)Benefits:
- β Preserves Terraform formatting and comments
- β Handles complex nested structures safely
- β Prevents syntax errors from malformed updates
- β Supports dynamic parameter paths
Comprehensive pre-flight validation prevents runtime errors:
# Example validation output
Configuration validation error: Repository 1, File 1: Missing required field 'path'
Configuration validation error: Repository 2: 'owner' must be a non-empty string
Configuration validation error: Setting 'create_pr' must be a booleanValidation Features:
- Structure Validation: Ensures all required fields are present
- Type Checking: Validates data types for all configuration values
- Logic Validation: Checks for logical inconsistencies
- Context-Aware Errors: Provides specific field and location information
Advanced GitHub API management:
# Automatic rate limit handling
rate_limit = github_client.get_rate_limit()
if rate_limit.core.remaining < 50:
wait_time = calculate_reset_wait_time()
logger.warning(f"Rate limit low. Waiting {wait_time} seconds...")
time.sleep(wait_time)Features:
- Proactive Monitoring: Checks remaining API calls before each request
- Automatic Throttling: Pauses execution when limits are approached
- Intelligent Recovery: Resumes processing after rate limit reset
- Graceful Degradation: Continues operation under API constraints
Unique, collision-free branch naming:
# Generated branch names
terraform-automation-webapp-20240115-143022
terraform-automation-api-20240115-143045
terraform-automation-database-20240115-143108Features:
- Timestamp Integration: Ensures uniqueness across executions
- Repository Context: Includes repository identifier for clarity
- Collision Prevention: Eliminates branch naming conflicts
- Clean Naming: Follows Git branch naming conventions
| Input | Description | Required | Type | Default | Validation |
|---|---|---|---|---|---|
config_file |
Path to configuration file | No | String | config.yaml |
File existence validated |
dry_run |
Preview changes without applying | No | Boolean | false |
- |
base_branch |
Base branch for feature branches | No | String | main |
Branch existence checked |
branch_prefix |
Prefix for created branches | No | String | terraform-automation |
Alphanumeric validation |
auto_close_obsolete |
Automatically close obsolete PRs | No | Boolean | false |
- |
slack_webhook_url |
Slack webhook URL for notifications | No | String | "" |
URL format validated |
debug_mode |
Enable debug logging for troubleshooting | No | Boolean | false |
- |
- name: Validate configuration file
run: |
if [ ! -f "${{ env.CONFIG_FILE }}" ]; then
echo "β Configuration file not found!"
exit 1
fi
echo "β
Configuration validated"- name: Display configuration summary
run: |
echo " π§ Configuration Summary:"
echo " π Config file: ${{ env.CONFIG_FILE }}"
echo " πΏ Base branch: ${{ env.BASE_BRANCH }}"
echo " ποΈ Dry run: ${{ env.DRY_RUN }}"- name: Install Python dependencies
run: |
if [ -f "requirements.txt" ]; then
pip3 install -r requirements.txt
else
pip3 install PyGithub python-hcl2 PyYAML requests
fi
echo "β
Dependencies installed successfully"Scenario: Update application version across multiple microservice repositories with team notifications
repositories:
- owner: "mycompany"
repo: "user-service"
files:
- path: "variables.tf"
changes:
variables:
- app_version:
default:
update:
- from: ["1.2.3", "1.2.4"]
to: "1.3.0"
param_not_found:
action: add
value: "1.3.0"
- owner: "mycompany"
repo: "payment-service"
files:
- path: "variables.tf"
changes:
variables:
- app_version:
default:
update:
- from: ["1.2.3", "1.2.4"]
to: "1.3.0"
settings:
pr_title_template: "π Update application version to 1.3.0 - {{timestamp}}"
slack:
username: "Deployment Bot"
icon_emoji: ":rocket:"
notify_on_success: true
notify_batch_summary: true
include_changes_summary: trueScenario: Scale EC2 instances and update spot pricing across environments with detailed notifications
repositories:
- owner: "mycompany"
repo: "production-infrastructure"
files:
- path: "compute.tf"
changes:
resources:
- aws_instance.web_server:
# Scale instance type
instance_type:
update:
- from: ["t3.medium", "t3.large"]
to: "t3.xlarge"
param_not_found:
action: error # Critical parameter
# Update spot pricing (nested parameter)
instance_market_options.spot_options.max_price:
update:
- from: ["0.05", "0.08"]
to: "0.12"
param_not_found:
action: add
value: "0.12"
# Increase root volume (deeply nested)
root_block_device.ebs.volume_size:
update:
- from: ["50", "80"]
to: "120"
settings:
pr_title_template: "π Scale production infrastructure resources - {{timestamp}}"
slack:
username: "Infrastructure Bot"
icon_emoji: ":chart_with_upwards_trend:"
channel: "#infrastructure-alerts"
notify_on_success: true
notify_on_error: true
include_changes_summary: true
max_changes_displayed: 10Our enhanced Slack integration provides rich, contextual notifications with detailed formatting and comprehensive information about your infrastructure changes.
- Rich Message Formatting: Beautiful, structured messages with clear sections and visual indicators
- Contextual Information: Repository details, file counts, change summaries, and direct links
- Multiple Notification Types: Success notifications, error alerts, and batch processing summaries
- Workflow Integration: Direct links to GitHub Actions runs for debugging and audit trails
- Customizable Appearance: Configure bot username, emoji, and notification preferences
- Change Tracking: Detailed summaries of what parameters were changed and their values
Option 1: Workflow Input Parameter
# When manually triggering the workflow
slack_webhook_url: "YOUR_SLACK_WEBHOOK_URL_HERE"Option 2: Repository Secret (Recommended)
# Set SLACK_WEBHOOK_URL as repository secret (more secure)
# Go to: Repository Settings β Secrets and variables β Actions β New repository secret
Name: SLACK_WEBHOOK_URL
Secret: YOUR_SLACK_WEBHOOK_URL_HERE- Access Slack Apps: Visit https://api.slack.com/apps
- Create New App:
- Click "Create New App" β "From scratch"
- Name: "Terraform Automation Bot"
- Workspace: Select your workspace
- Enable Incoming Webhooks:
- Navigate to "Incoming Webhooks" in the left sidebar
- Toggle "Activate Incoming Webhooks" to On
- Click "Add New Webhook to Workspace"
- Configure Channel:
- Select the channel where notifications should be posted
- Click "Allow" to authorize the webhook
- Copy Webhook URL:
- Copy the generated webhook URL (starts with
https://hooks.slack.com/services/...) - Add it to your repository secrets or workflow configuration
- Copy the generated webhook URL (starts with
β Successful PR Creation
π’ Terraform Infrastructure Update - Completed Successfully
Repository: mycompany/webapp-infrastructure
Files Modified: 3
Pull Request: View PR
Workflow Run: View Execution
Changes Applied:
β’ Updated app_version: 1.2.3 β 1.3.0
β’ Updated instance_type: t3.medium β t3.large
β’ Added vpc_cidr: 10.1.0.0/16
β’ Updated kubernetes_version: 1.27 β 1.28
β’ ... and 2 more changes
π Batch Processing Summary
β
Infrastructure Update Batch Complete
Summary:
β’ Total repositories: 5
β’ Successful: 4
β’ Failed: 1
β’ PRs created: 4
Created Pull Requests:
β’ mycompany/webapp-infrastructure PR #123
β’ mycompany/api-service PR #87
β’ mycompany/database-infra PR #45
β’ mycompany/monitoring-stack PR #12
β Error Notification
π΄ Terraform Automation Error
Repository: mycompany/problematic-repo
Error: Configuration validation failed: Missing required field 'path'
Logs: View Execution Logs
Customize your Slack integration by adding a slack section to your config.yaml:
settings:
slack:
username: "Infrastructure Bot" # Custom bot display name
icon_emoji: ":robot_face:" # Custom bot emoji
channel: "#infrastructure-updates" # Optional channel override
notify_on_success: true # Enable success notifications
notify_on_error: true # Enable error notifications
notify_batch_summary: true # Enable batch summaries
include_changes_summary: true # Include detailed change lists
max_changes_displayed: 5 # Limit changes shown (prevents spam)
include_workflow_links: true # Include GitHub Actions linksThe tool provides comprehensive, structured logging with enhanced change tracking:
2024-01-15 10:30:15 - INFO - Starting Terraform Infrastructure Update Automation
2024-01-15 10:30:16 - INFO - Configuration loaded successfully: 3 repositories
2024-01-15 10:30:17 - INFO - ============================================================
2024-01-15 10:30:17 - INFO - Processing repository 1/3: mycompany/webapp-infrastructure
2024-01-15 10:30:18 - DEBUG - GitHub API rate limit: 4850 requests remaining
2024-01-15 10:30:19 - INFO - Created branch 'terraform-automation-webapp-20240115-103019'
2024-01-15 10:30:20 - INFO - Processing file: variables.tf
2024-01-15 10:30:21 - INFO - Updated variable 'app_version' default to '1.3.0'
2024-01-15 10:30:22 - DEBUG - Terraform formatting applied
2024-01-15 10:30:23 - INFO - Successfully committed changes to variables.tf
2024-01-15 10:30:24 - INFO - β
Pull Request created: https://github.com/mycompany/webapp-infrastructure/pull/123
2024-01-15 10:30:25 - INFO - β
Slack notification sent successfully
- Location:
terraform-automation-YYYYMMDD.log - Content: Complete operation history with timestamps and change details
- Retention: Configurable (default: workspace cleanup)
- Format: Structured logging for easy parsing and analysis
- Temporary Files: Uploaded as workflow artifacts on failures
- Debug Information: Complete parameter processing logs with change summaries
- Stack Traces: Full error context for troubleshooting
The enhanced notification system can be extended to support additional integrations:
# Example: Microsoft Teams integration
def send_teams_notification(webhook_url: str, message: str, blocks: List[Dict]):
# Custom Teams implementation with rich cards
pass
# Example: Discord integration
def send_discord_notification(webhook_url: str, message: str, embeds: List[Dict]):
# Custom Discord implementation with rich embeds
pass
# Example: Email integration
def send_email_notification(smtp_config: Dict, message: str, recipients: List[str]):
# Custom email implementation for critical alerts
pass- Use Repository Secrets: Never commit webhook URLs to your codebase
- Rotate Webhooks Regularly: Generate new webhooks periodically for security
- Monitor Usage: Review webhook activity in Slack app management console
- Principle of Least Privilege: Only grant necessary channel permissions
- Audit Integration: Regularly review which repositories have access to webhook URLs
# Keep configuration files in version control
git add config.yaml requirements.txt
git commit -m "Add infrastructure automation config with Slack integration"
git push origin mainsettings:
pr_title_template: "π§ [{{timestamp}}] Infrastructure Update: {{change_summary}}"
commit_message_template: "Automated update: {{change_summary}} - {{timestamp}}"
slack:
username: "Infrastructure Assistant"
icon_emoji: ":gear:"
include_changes_summary: true# config-production.yaml
repositories:
- owner: "mycompany"
repo: "prod-infrastructure"
settings:
slack:
channel: "#prod-infrastructure"
notify_on_error: true
notify_batch_summary: true
# config-development.yaml
repositories:
- owner: "mycompany"
repo: "dev-infrastructure"
settings:
slack:
channel: "#dev-infrastructure"
notify_on_success: false # Reduce noise in dev
notify_on_error: true# GitHub token should have minimal required scopes:
# - repo (for repository access)
# - workflow (if modifying workflows)
# Avoid: admin, delete_repo, or other excessive permissions# Use GitHub Secrets for sensitive data
# Never commit API tokens or webhook URLs to code
echo "SLACK_WEBHOOK_URL=xxx" >> .env # β Wrong
# Instead: Add via GitHub UI β Settings β Secrets# Configure branch protection rules for target repositories
# Require PR reviews for infrastructure changes
# Enable status checks before merging# Always test with dry_run first
DRY_RUN=true python3 main.py
# Test in development repositories before production
# Use staging environments for validation
# Test Slack notifications in dedicated channels# Use descriptive PR titles and commit messages
# Maintain change logs and documentation
# Link changes to project tracking systems
# Leverage Slack notifications for change awareness# Monitor workflow execution and failure rates
# Set up alerts for repeated failures
# Review logs regularly for optimization opportunities
# Track Slack notification delivery rates| Issue Category | Symptoms | Diagnostic Steps | Solution |
|---|---|---|---|
| Configuration | Validation errors on startup | Check config.yaml syntax | Use YAML validator, verify required fields |
| Permissions | 401/403 GitHub API errors | Test token permissions | Regenerate token with repo scope |
| File Access | 404 errors on file retrieval | Verify file paths | Check repository structure and file names |
| Rate Limits | 403 rate limit exceeded | Monitor API usage | Tool handles automatically, check logs |
| Parsing | HCL parsing failures | Review Terraform syntax | Ensure valid Terraform files |
| Networking | Timeout errors | Check connectivity | Verify GitHub/Slack URLs are accessible |
| Slack Integration | Notification failures | Test webhook URL | Verify webhook is active and URL is correct |
| Rich Formatting | Malformed Slack messages | Check message size | Reduce change summary length |
| Issue | Symptoms | Solution |
|---|---|---|
| Configuration validation errors | Configuration validation error: Repository 1, File 1: Missing required field 'path' |
Verify config.yaml structure matches examples exactly |
| Repository access errors | 404 {"message": "Not Found"} |
Ensure repositories exist and GitHub token has access |
| File not found errors | Error getting contents for file.tf: 404 |
Verify file paths in config.yaml match actual repository structure |
| Issue | Symptoms | Solution |
|---|---|---|
| Token not found | KeyError: 'GITHUB_TOKEN' |
Set environment variable: export GITHUB_TOKEN="your_token" |
| Insufficient permissions | 403 Forbidden |
Ensure token has repo scope and organization access |
| Rate limiting | 403 rate limit exceeded |
Tool handles automatically, but reduce concurrent operations if needed |
| Issue | Symptoms | Solution |
|---|---|---|
| CIDR block formatting | Invalid number literal: 10.1.0.0/16 |
Should be automatically quoted by tool |
| Array formatting | "["item1", "item2"]" double quotes |
Check _format_terraform_value function |
| Complex expressions | Quoted expressions that shouldn't be | Tool detects data., var., operators automatically |
Common Issues:
| Issue | Symptoms | Solution |
|---|---|---|
| Invalid Webhook URL | 404 Client Error: Not Found |
Verify webhook URL format and regenerate if needed |
| Channel Permissions | 403 Forbidden |
Ensure app has permission to post to target channel |
| Webhook Deactivated | 404 Not Found |
Check if webhook was deactivated in Slack app settings |
| Network Timeout | Timeout after 10 seconds |
Check network connectivity and Slack service status |
Validation Steps:
# Test webhook manually
curl -X POST -H 'Content-type: application/json' \
--data '{"text":"Test from Terraform Bot"}' \
YOUR_SLACK_WEBHOOK_URL
# Check GitHub Actions logs for Slack-related messages
grep -i "slack|notification" terraform-automation-*.log# Find successful operations with change details
grep "β
|Successfully|created|Updated.*parameter" terraform-automation-*.log
# Identify configuration issues including Slack settings
grep "Configuration validation error|β|Slack.*error" terraform-automation-*.log
# Monitor API rate limiting and Slack delivery
grep -i "rate limit|throttl|slack.*sent|slack.*failed" terraform-automation-*.log
# Track parameter changes with summaries
grep "Updated.*parameter|Added.*parameter|Change summary" terraform-automation-*.log
# Find error patterns including notification failures
grep -A5 -B5 "Error|Exception|Failed|Slack.*failed" terraform-automation-*.log
# Check Slack notifications and delivery status
grep "Slack|notification.*sent|notification.*failed" terraform-automation-*.log
# Analyze rich formatting and message truncation
grep "rich formatting|truncated|fallback.*message" terraform-automation-*.log# 1. Identify failed repositories from logs
grep "β.*Error processing repository" terraform-automation-*.log
# 2. Create focused configuration for failed repos only
# Edit config.yaml to include only failed repositories
# 3. Re-run with specific configuration and Slack notifications
config_file: "config-retry.yaml"
slack_webhook_url: "your-webhook-url"# List automation branches
git branch -r | grep terraform-automation
# Cleanup old branches (if needed manually)
git push origin --delete terraform-automation-old-branch-name# Test Slack webhook manually
curl -X POST -H 'Content-type: application/json' \
--data '{"text":"Manual test - Terraform Bot is working"}' \
$SLACK_WEBHOOK_URL
# Regenerate webhook if needed
# Go to Slack App settings β Incoming Webhooks β Add New Webhook- Dynamic Expressions: Complex Terraform expressions may require manual intervention
- State Dependencies: Tool doesn't handle Terraform state or state migration
- Custom Providers: Limited support for custom or proprietary Terraform providers
- Complex Modules: Very complex nested module structures may need specialized handling
- Resource updates: Some resource parameter updates may show warnings like "Parameter 'X' not found for update"
- Nested parameters: Complex nested structures work but may require specific syntax
- HCL parsing: Falls back to regex for complex structures
- Repository Size: Very large repositories (>10,000 files) may experience slower processing
- API Limits: GitHub API rate limits may slow processing for organizations with 500+ repositories
- Concurrent Processing: Currently processes repositories sequentially (parallel processing planned)
- Slack Rate Limits: High-frequency notifications may hit Slack API limits
- Limited Integrations: Currently supports GitHub and Slack only (Teams, Discord planned)
- Custom Validation: Business-specific validation logic must be implemented separately
- Terraform Planning: Doesn't execute
terraform planor validate infrastructure impact - State Management: No integration with Terraform state backends or remote state
- Policy Enforcement: Doesn't integrate with policy-as-code tools like OPA or Sentinel
- For resource updates: Ensure parameters exist in the target files
- For complex nesting: Test with dry-run first
- For new resources: Use
param_not_found: action: addconfiguration
- Parallel Processing: Process multiple repositories concurrently
- Enhanced Validation: Terraform syntax validation before commits
- Custom Hooks: Pre/post-processing hooks for custom logic
- Microsoft Teams: Support for Teams notifications with rich formatting
- Slack Thread Support: Group related notifications in Slack threads
- Terraform Plan Integration: Optional plan execution and output in notifications
- Policy Validation: Integration with policy frameworks
- Advanced Templating: Jinja2-based template support for complex scenarios
- GitLab Integration: Support for GitLab repositories
- Discord Integration: Rich Discord notifications with embeds
- Multi-Cloud Support: Enhanced support for Azure, GCP providers
- Enterprise Features: SSO integration, advanced RBAC, compliance reporting
- AI-Powered Suggestions: Smart parameter update recommendations
- Advanced Analytics: Detailed metrics and insights on infrastructure automation patterns
- Manual Process: 15-30 minutes per repository for parameter updates
- Automated Process: 30 seconds per repository
- Scale Impact: 95% time reduction for organizations with 100+ repositories
- Notification Overhead: 0 minutes (automated Slack notifications eliminate manual status updates)
- Manual Process: ~5-10% error rate due to copy-paste mistakes
- Automated Process: <0.1% error rate with validation and testing
- Quality Impact: 50x improvement in change accuracy
- Communication Gaps: Eliminated through automated Slack notifications
- Manual Process: Inconsistent formatting, descriptions, and timing
- Automated Process: Identical changes across all repositories
- Compliance: 100% consistency for audit and compliance requirements
- Team Awareness: Real-time notifications ensure team alignment
- Focus Shift: Engineers work on strategic initiatives instead of operational tasks
- Context Switching: Eliminate repository-by-repository manual updates
- Skill Utilization: Better use of engineering talent on value-adding activities
- Team Collaboration: Enhanced visibility through rich Slack notifications
- Human Error Elimination: Remove manual copy-paste mistakes
- Audit Trail: Complete history of all infrastructure changes with notifications
- Rollback Capability: Easy reversion through standard Git workflows
- Team Awareness: Immediate notification of errors and issues
- Scalability: Handle hundreds of repositories without linear effort increase
- Standardization: Enforce consistent infrastructure patterns
- Compliance: Automated documentation and change tracking
- Transparency: Real-time visibility into infrastructure automation progress
- Rich Notifications: Detailed Slack notifications keep teams informed with context
- Traceability: Complete change history with links to automation runs and PRs
- Review Process: Standard PR workflow for all infrastructure changes
- Error Handling: Immediate notification and debugging information for failures
- Manual Updates: 2-4 hours per batch update across 20 repositories
- Error Resolution: 30-60 minutes per manual error
- Status Communication: 15-30 minutes for manual status updates
- Change Tracking: Manual documentation and communication
- Automated Updates: 5-10 minutes for 20 repositories
- Error Resolution: 5-10 minutes with direct links to logs and debugging information
- Status Communication: 0 minutes (automated rich notifications)
- Change Tracking: Automatic with detailed summaries and audit trails
# Clone and set up development environment
git clone https://github.com/aws-samples/sample-terraform-pr-automation-utility
cd sample-terraform-pr-automation-utility
# Create virtual environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install dependencies
pip install -r requirements.txt
# Install development dependencies (if available)
pip install -r requirements-dev.txtsample-terraform-pr-automation-utility/
βββ main.py # Main application logic with enhanced Slack integration
βββ config.yaml # Example configuration with Slack settings
βββ requirements.txt # Python dependencies
βββ .gitignore # Git ignore rules
βββ .github/
β βββ workflows/
β βββ grouping-action.yaml # GitHub Actions workflow
βββ examples/
βββ config.example.yaml # Template configuration
βββ github-test-contents/ # Example terraform modules
βββ repos/
βββ terraform-modules/
β βββ modules/
β βββ eks/
β βββ rds/
βββ terraform-pr-automation-tool/
- Type Hints: All functions must include Python type hints
- Documentation: Comprehensive docstrings for all public functions
- Logging: Structured logging with appropriate levels
- Error Handling: Graceful error handling with informative messages and Slack notifications
# Run unit tests
python -m pytest tests/unit/
# Run integration tests (including Slack webhook testing)
python -m pytest tests/integration/
# Test configuration validation including Slack settings
python -c "from main import validate_config, get_config_content; validate_config(get_config_content())"
# Test with sample configuration
DRY_RUN=true python main.py# Test Slack webhook connectivity
curl -X POST -H 'Content-type: application/json' \
--data '{"text":"Development test from Terraform Bot"}' \
$SLACK_WEBHOOK_URL
# Test rich formatting
python -c "
from main import send_slack_notification, create_terraform_notification_blocks
blocks = create_terraform_notification_blocks('test/repo', 'https://github.com/test/repo/pull/1', 2, ['Test change'])
send_slack_notification('Test message', blocks=blocks)
"Β© 2025 Amazon Web Services, Inc. or its affiliates. All Rights Reserved. This AWS Content is provided subject to the terms of the AWS Customer Agreement available at http://aws.amazon.com/agreement or other written agreement between Customer and either Amazon Web Services, Inc. or Amazon Web Services EMEA SARL or both.
- Ashish Bhatt
- Matt Padgett
- Prafful Gupta
- Sandip Gangapadhyay
- Ashwin Divakaran
