Skip to content

Instantly share code, notes, and snippets.

@jpedro
Created November 19, 2021 21:12
Show Gist options
  • Select an option

  • Save jpedro/dbc54bbb18243a2ecbbfe4c3664de308 to your computer and use it in GitHub Desktop.

Select an option

Save jpedro/dbc54bbb18243a2ecbbfe4c3664de308 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
# File in .github/scripts/check-plan.py
"""
Validates a terraform plan file to detect resource deletions. Supports
whitelisting of providers and resources that can be deleted safely.
"""
import argparse
import json
# All resources under this list can be deleted!
ALLOWED_PROVIDERS = [
"registry.terraform.io/hashicorp/null",
]
ALLOWED_RESOURCES = [
"aws_s3_bucket",
"aws_s3_bucket_policy",
]
def main(file: str):
print(f"==> Checking plan from file '{file}'")
with open(file) as f:
data = json.load(f)
if not "resource_changes" in data:
print(f"==> SKIP: Plan has only creates and in-place updates")
return 0
changes = data["resource_changes"]
for change in changes:
provider = change["provider_name"]
resource = f"[{provider}] {change['type']}.{change['name']}"
if not "delete" in change["change"]["actions"]:
ops = ", ".join(change['change']['actions'])
print(f"==> SKIP: Resource {resource} has just {ops} operations.")
continue
if provider in ALLOWED_PROVIDERS:
print(f"==> PASS: Delete on provider {provider} is ok.")
elif change["type"] in ALLOWED_RESOURCES:
print(f"==> PASS: Delete on resource {resource} is ok.")
else:
print(f"==> ABORT: Delete not allowed on {resource}.")
return 1
print(f"==> PASS: Plan is allowed")
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Checks a terraform plan.")
parser.add_argument("file", type=str, help="Plan file")
args = parser.parse_args()
exit(main(args.file))
# File in .github/workflows/terraform.yaml
name: Terraform
on:
pull_request:
push:
branches:
- master
jobs:
terraform:
name: "Terraform"
runs-on: ubuntu-latest
container:
image: jpedrob/cicd
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Terraform plan
working-directory: terraform
env:
AWS_ACCESS_KEY_ID: "${{ secrets.AWS_ACCESS_KEY_ID }}"
AWS_SECRET_ACCESS_KEY: "${{ secrets.AWS_SECRET_ACCESS_KEY }}"
run: |
terraform fmt -check -recursive
terraform init -reconfigure
terraform validate
terraform plan -out plan.tfplan
terraform show -json plan.tfplan > plan.json
../.github/scripts/check-plan.py plan.json
- name: Terraform apply
working-directory: terraform
if: github.ref == 'refs/heads/master'
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
run: |
../.github/scripts/check-plan.py plan.json
terraform apply --auto-approve plan.tfplan
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment