Skip to content

aws-samples/sample-terraform-pr-automation-utility

Automated Terraform Infrastructure Update Workflow using GitHub Actions

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.

πŸš€ Overview

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.

πŸ“‹ Table of Contents

🎯 Problem Statement

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

πŸ’‘ Solution Overview

Our automation tool transforms infrastructure management through a configuration-driven approach that:

  1. Eliminates Manual Work: Automates the entire workflow from configuration changes to PR creation
  2. Ensures Consistency: Applies identical changes across all targeted repositories with guaranteed consistency
  3. Provides Intelligence: Advanced HCL parsing handles complex nested Terraform structures automatically
  4. Offers Transparency: Comprehensive logging and validation provide full visibility into all operations
  5. Enhances Team Collaboration: Rich Slack notifications keep teams informed with contextual information and direct links
  6. Integrates Seamlessly: Optional integrations maintain existing workflow continuity while adding powerful automation
  7. Scales Effortlessly: Processes hundreds of repositories efficiently with built-in rate limiting and error handling

✨ Key Features

🧠 Intelligent Terraform Processing

  • 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 fmt integration

πŸ›‘οΈ Enterprise-Grade Validation

  • 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

πŸ“Š Production-Ready Logging

  • 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

πŸ”„ Robust Operation Management

  • 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

πŸ’¬ Enhanced Team Integration

  • 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

πŸ—οΈ Architecture

Architecture Diagram

Workflow Components

  1. Configuration Engine: Validates and processes user-defined changes
  2. Repository Manager: Handles GitHub API interactions with rate limiting
  3. Terraform Processor: Advanced HCL parsing and intelligent parameter updates
  4. Change Detector: Identifies actual modifications to prevent unnecessary operations
  5. Enhanced Notification Hub: Manages rich Slack integration with contextual notifications
  6. Logging System: Comprehensive audit trail and monitoring

πŸ“‹ Prerequisites

Required Components

  • Python 3.8+: Tested with Python 3.8 and above
  • GitHub Personal Access Token: With repo scope and organization access
  • Target Repositories: Must exist and be accessible with your token
  • Terraform CLI: For formatting (optional but recommended)

GitHub Token Setup

  1. Visit: https://github.com/settings/tokens
  2. Generate new token (classic)
  3. Select scopes: repo, workflow (if needed), read:org (for organization repos)
  4. Copy token immediately (you won't see it again)
  5. Set environment variable: export GITHUB_TOKEN="your_token"

Repository Requirements

  • 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

Required Secrets

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

GitHub Token Permissions

Your GitHub token must have the following permissions:

  • repo - Full repository access
  • workflow - Access to GitHub Actions (if modifying workflows)
  • read:org - Organization access (for organization-owned repositories)

πŸ› οΈ Installation and Setup

⚠️ 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.

1. Repository Setup

# 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

2. Install Dependencies

# 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')"

3. Configure GitHub Token

# 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/user

4. Configuration File Setup

Edit 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: true

πŸ§ͺ Testing and Validation

Pre-flight Testing

Always 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

Repository Access Verification

# Test GitHub token access
curl -H "Authorization: token $GITHUB_TOKEN" \
  https://api.github.com/repos/owner/repo-name

# Should return repository information, not 404

Configuration Validation

# 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}')
"

πŸ“– Configuration Guide

Basic Configuration Structure

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 shown

Parameter Action Types

Update Actions

Modify 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

Parameter Not Found Actions

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

Advanced Configuration Examples

Nested Parameter Handling

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"

Multiple Update Rules

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 parameter

πŸ“‹ Tested Configuration Example

This 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: true

πŸš€ Quick Start (Tested)

1. Clone and Setup

git clone https://github.com/aws-samples/sample-terraform-pr-automation-utility
cd sample-terraform-pr-automation-utility
pip3 install -r requirements.txt

2. Configure GitHub Token

export GITHUB_TOKEN="your_github_token_here"

3. Test Configuration

# 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

4. Run Automation

# Run actual automation
python3 main.py

5. Monitor Results

  • Check logs for processing status
  • Review created pull requests
  • Monitor Slack notifications (if configured)

πŸ“Š Success Metrics

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

Expected Log Messages

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

πŸš€ Advanced Features

πŸ” Enhanced HCL Parsing

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

πŸ›‘οΈ Configuration Validation System

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 boolean

Validation 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

πŸ”„ Intelligent Rate Limiting

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

🏷️ Smart Branch Management

Unique, collision-free branch naming:

# Generated branch names
terraform-automation-webapp-20240115-143022
terraform-automation-api-20240115-143045  
terraform-automation-database-20240115-143108

Features:

  • 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

πŸ”§ GitHub Actions Workflow

Workflow Inputs

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 -

Workflow Features

🎯 Pre-execution Validation

- name: Validate configuration file
  run: |
    if [ ! -f "${{ env.CONFIG_FILE }}" ]; then
      echo "❌ Configuration file not found!"
      exit 1
    fi
    echo "βœ… Configuration validated"

πŸ“Š Enhanced Status Reporting

- 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 }}"

πŸ”„ Streamlined Dependency Installation

- 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"

πŸ“ Usage Examples

Example 1: Simple Application Version Update with Slack Notifications

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: true

Example 2: Infrastructure Scaling with Rich Notifications

Scenario: 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: 10

πŸ’¬ Enhanced Slack Integration

Our enhanced Slack integration provides rich, contextual notifications with detailed formatting and comprehensive information about your infrastructure changes.

Key Features

  • 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

Setup Options

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

Creating a Slack Webhook

  1. Access Slack Apps: Visit https://api.slack.com/apps
  2. Create New App:
    • Click "Create New App" β†’ "From scratch"
    • Name: "Terraform Automation Bot"
    • Workspace: Select your workspace
  3. Enable Incoming Webhooks:
    • Navigate to "Incoming Webhooks" in the left sidebar
    • Toggle "Activate Incoming Webhooks" to On
    • Click "Add New Webhook to Workspace"
  4. Configure Channel:
    • Select the channel where notifications should be posted
    • Click "Allow" to authorize the webhook
  5. Copy Webhook URL:
    • Copy the generated webhook URL (starts with https://hooks.slack.com/services/...)
    • Add it to your repository secrets or workflow configuration

Notification Examples

βœ… 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

Configuration Options

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 links

πŸ“Š Logging and Monitoring

Enhanced Log Levels and Output

The tool provides comprehensive, structured logging with enhanced change tracking:

Console Output (Real-time)

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

File Logs (Audit Trail)

  • 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

Error Artifacts (Failure 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

πŸ”— Integration Options

Custom Webhooks and Extensions

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

Webhook Security Best Practices

  1. Use Repository Secrets: Never commit webhook URLs to your codebase
  2. Rotate Webhooks Regularly: Generate new webhooks periodically for security
  3. Monitor Usage: Review webhook activity in Slack app management console
  4. Principle of Least Privilege: Only grant necessary channel permissions
  5. Audit Integration: Regularly review which repositories have access to webhook URLs

🎯 Best Practices

Configuration Management

1. Version Control Everything

# 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 main

2. Use Descriptive Templates

settings:
  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

3. Environment-Specific Configurations

# 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

Security Best Practices

1. Minimal Token Permissions

# GitHub token should have minimal required scopes:
# - repo (for repository access)
# - workflow (if modifying workflows)
# Avoid: admin, delete_repo, or other excessive permissions

2. Secret Management

# 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

3. Branch Protection

# Configure branch protection rules for target repositories
# Require PR reviews for infrastructure changes
# Enable status checks before merging

Operational Excellence

1. Testing Strategy

# 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

2. Change Management

# Use descriptive PR titles and commit messages
# Maintain change logs and documentation
# Link changes to project tracking systems
# Leverage Slack notifications for change awareness

3. Monitoring and Alerting

# Monitor workflow execution and failure rates
# Set up alerts for repeated failures
# Review logs regularly for optimization opportunities
# Track Slack notification delivery rates

πŸ› Troubleshooting

Common Issues and Solutions

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

Configuration Issues

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

GitHub Token Issues

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

Terraform Syntax Issues

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

Slack Integration Issues

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

Enhanced Log Analysis Commands

# 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

Recovery Procedures

Partial Failure Recovery

# 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"

Branch Cleanup

# List automation branches
git branch -r | grep terraform-automation

# Cleanup old branches (if needed manually)
git push origin --delete terraform-automation-old-branch-name

Slack Integration Recovery

# 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

⚠️ Known Limitations

Current Constraints

Terraform Complexity

  • 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 Parameter Limitations

  • 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

Scale Limitations

  • 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

Integration Features

  • 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 plan or 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

Current Workarounds

  • 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: add configuration

Planned Enhancements

Short Term (Next Release)

  • 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

Medium Term (Future Releases)

  • 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

Long Term (Roadmap)

  • 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

βœ… Benefits

Quantifiable Impact

Time Savings

  • 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)

Error Reduction

  • 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

Consistency Improvement

  • 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

Strategic Benefits

πŸš€ Developer Productivity

  • 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

πŸ›‘οΈ Risk Mitigation

  • 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

πŸ“ˆ Operational Excellence

  • 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

πŸ”„ Team Collaboration

  • 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

Team Productivity Metrics

Before Automation

  • 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

After Automation with Enhanced Slack Integration

  • 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

πŸ§ͺ Development

Development Setup

# 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.txt

Code Structure

sample-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/

Development Guidelines

Code Quality Standards

  • 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

Testing Requirements

# 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

Slack Integration Testing

# 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)
"

πŸ“„ License

Β© 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.

πŸ‘¨β€πŸ’» Contributors

  • Ashish Bhatt
  • Matt Padgett
  • Prafful Gupta
  • Sandip Gangapadhyay
  • Ashwin Divakaran

About

Configuration-driven automation tool for creating Pull Requests across multiple Terraform repositories

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages