Skip to content

#43 Terraform Drift Detectionの実行フローを改善し、ディレクトリごとの初期化とプラン実行を追加 #24

#43 Terraform Drift Detectionの実行フローを改善し、ディレクトリごとの初期化とプラン実行を追加

#43 Terraform Drift Detectionの実行フローを改善し、ディレクトリごとの初期化とプラン実行を追加 #24

Workflow file for this run

name: Terraform Drift Detection
on:
schedule:
- cron: '0 3 * * *' # 毎日03:00 JST(=18:00 UTC)
workflow_dispatch: # 手動実行も可能にする
push:
branches:
- '43-drift' # テスト用に43-driftブランチでも実行
jobs:
drift-detection:
runs-on: arc-runner-set
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
- name: Install AWS CLI
run: |
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
aws --version
- name: Set up Terraform
uses: hashicorp/setup-terraform@v3
with:
terraform_version: 1.11.3
terraform_wrapper: false
- name: Find Terraform Directories
id: find_dirs
run: |
TERRAFORM_DIRS=$(find . -name "*.tf" -type f | xargs dirname | sort -u | tr '\n' ' ')
echo "terraform_dirs=$TERRAFORM_DIRS" >> $GITHUB_OUTPUT
echo "Found Terraform directories: $TERRAFORM_DIRS"
- name: Run Terraform Drift Detection
id: drift_check
run: |
TERRAFORM_DIRS="${{ steps.find_dirs.outputs.terraform_dirs }}"
FAILED_DIRS=""
ALL_OUTPUT=""
for dir in $TERRAFORM_DIRS; do
echo "=== Checking directory: $dir ==="
cd "$GITHUB_WORKSPACE/$dir"
# Skip directories without terraform.tf or _versions.tf (not initialized modules)
if [[ ! -f terraform.tf && ! -f _versions.tf ]]; then
echo "Skipping $dir - no terraform.tf or _versions.tf found"
continue
fi
# Terraform Init
echo "Running terraform init in $dir"
if ! terraform init -input=false; then
echo "Failed to initialize $dir"
FAILED_DIRS="$FAILED_DIRS $dir"
continue
fi
# Terraform Plan
echo "Running terraform plan in $dir"
set +e
terraform plan -detailed-exitcode -no-color > "/tmp/plan_${dir//\//_}.txt" 2>&1
PLAN_EXIT_CODE=$?
set -e
PLAN_CONTENT=$(cat "/tmp/plan_${dir//\//_}.txt")
echo "$PLAN_CONTENT"
if [[ $PLAN_EXIT_CODE -eq 1 ]]; then
echo "Plan failed in $dir with exit code $PLAN_EXIT_CODE"
FAILED_DIRS="$FAILED_DIRS $dir"
ALL_OUTPUT="$ALL_OUTPUT\n=== Directory: $dir ===\n$PLAN_CONTENT\n"
elif [[ $PLAN_EXIT_CODE -eq 2 ]]; then
echo "Changes detected in $dir"
FAILED_DIRS="$FAILED_DIRS $dir"
ALL_OUTPUT="$ALL_OUTPUT\n=== Directory: $dir ===\n$PLAN_CONTENT\n"
else
echo "No changes in $dir"
fi
done
if [[ -n "$FAILED_DIRS" ]]; then
echo "failed_dirs=$FAILED_DIRS" >> $GITHUB_OUTPUT
echo -e "$ALL_OUTPUT" > /tmp/all_plan_output.txt
echo "Drift detection failed in directories: $FAILED_DIRS"
exit 1
else
echo "All directories passed drift detection"
fi
- name: Send SNS Notification on Drift Detection
if: ${{ failure() && steps.drift_check.outputs.failed_dirs }}
run: |
FAILED_DIRS="${{ steps.drift_check.outputs.failed_dirs }}"
PLAN_OUTPUT=$(cat /tmp/all_plan_output.txt | head -100)
aws sns publish \
--topic-arn "arn:aws:sns:ap-northeast-2:456247443832:cn-practice-drift-notification" \
--subject "Terraform Drift Detected" \
--message "$(cat <<EOF
Terraform drift detected in the following directories:
$FAILED_DIRS
Workflow: ${{ github.workflow }}
Run ID: ${{ github.run_id }}
Repository: ${{ github.repository }}
Branch: ${{ github.ref_name }}
Plan Output (first 100 lines):
${PLAN_OUTPUT}
Full logs: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
EOF
)"