|
#!/usr/bin/env python3 |
|
# This only checks for terraform policy changes |
|
# Usage: |
|
# |
|
# terraform plan -out=terraform.tfplan |
|
# terraform show -no-color -json terraform.tfplan > terraform.tfplan.json |
|
# python find-tfpolicy-changes.py terraform.tfplan.json |
|
# |
|
import json |
|
import sys |
|
|
|
|
|
with open(sys.argv[1], "rb") as f: |
|
data = json.loads(f.read()) |
|
|
|
|
|
for resource in data['resource_changes']: |
|
before_policy = resource['change']['before'].get('policy') |
|
after_policy = resource['change']['after'].get('policy') |
|
if not before_policy or not after_policy: |
|
continue |
|
before_policy = json.loads(before_policy) |
|
after_policy = json.loads(after_policy) |
|
for idx in range(len(before_policy['Statement'])): |
|
before_statement = before_policy['Statement'] |
|
after_statement = after_policy['Statement'] |
|
if before_statement == after_statement: |
|
continue |
|
for key in before_statement[idx].keys(): |
|
if before_statement[idx][key] == after_statement[idx][key]: |
|
continue |
|
if not key.lower() in ['principal', 'action']: |
|
continue |
|
end_resource = [] |
|
try: |
|
after_principals = after_statement[idx][key]['AWS'] |
|
before_principals = before_statement[idx][key]['AWS'] |
|
end_resource = ['Principal', 'AWS'] |
|
except TypeError: |
|
after_principals = after_statement[idx][key] |
|
before_principals = before_statement[idx][key] |
|
end_resource = ['Action'] |
|
# remove duplicates and only find differences using set logic |
|
changes_after = list(set(after_principals) - set(before_principals)) |
|
changes_before = list(set(before_principals) - set(after_principals)) |
|
if len(changes_after) == 0 and len(changes_before) == 0: |
|
continue |
|
if len(changes_after) > 0: |
|
changes = changes_after |
|
else: |
|
changes = changes_before |
|
print( |
|
f"{resource['address']}.policy.Statement[{idx}]." |
|
f"{'.'.join(end_resource)}" |
|
) |
|
if len(changes) == 0: |
|
continue |
|
for change in changes: |
|
if change in before_principals: |
|
print('- {}'.format(change)) |
|
elif change in after_principals: |
|
print('+ {}'.format(change)) |
|
|
Nice work. Glad I could help get you started 😄