Skip to content

Commit

Permalink
initial new modules
Browse files Browse the repository at this point in the history
  • Loading branch information
badra001 committed Mar 10, 2026
1 parent b2f54d7 commit d688d75
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 11 deletions.
59 changes: 59 additions & 0 deletions local-app/python-tools/cross-organization/check_iam_roles.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import boto3
import json

# --- VERSIONING ---
__version__ = "1.0.0"

def account_task(account_session, account_id, account_name, region):
"""
Scans IAM roles to list metadata, policies, boundaries, and tags.
IAM is global; this runs once per account.
"""
results = {"alias": "N/A", "data": {}}
try:
iam = account_session.client('iam')
results["alias"] = iam.list_account_aliases().get('AccountAliases', ["N/A"])[0]

roles_paginator = iam.get_paginator('list_roles')

for page in roles_paginator.paginate():
for role in page['Roles']:
role_name = role['RoleName']

# 1. Attached (Managed) Policies
attached_policies = []
attached_paginator = iam.get_paginator('list_attached_role_policies')
for attached_page in attached_paginator.paginate(RoleName=role_name):
for policy in attached_page['AttachedPolicies']:
attached_policies.append(policy['PolicyName'])

# 2. Inline Policies
inline_policies = []
inline_paginator = iam.get_paginator('list_role_policies')
for inline_page in inline_paginator.paginate(RoleName=role_name):
inline_policies.extend(inline_page['PolicyNames'])

# 3. Permissions Boundary
boundary = role.get('PermissionsBoundary', {})
boundary_name = boundary.get('PermissionsBoundaryArn', 'N/A').split('/')[-1] if boundary else 'N/A'

# 4. Tags
# Boto3's list_roles returns tags in the main response structure
tags = {t['Key']: t['Value'] for t in role.get('Tags', [])}

results["data"][role_name] = {
"resource": role['Arn'],
"role_name": role_name,
"path": role['Path'],
"attached_policies": attached_policies,
"inline_policies": inline_policies,
"permissions_boundary": boundary_name,
"tags": tags
}

results["data"]["account_summary"] = {"_summary": f"ROLES:{len(results['data'])}"}

except Exception as e:
results["error"] = str(e)

return results
34 changes: 23 additions & 11 deletions local-app/python-tools/cross-organization/remediate_tgw_dns.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
#!/bin/env python3

import boto3
import sys
import os
import argparse

# --- VERSIONING ---
__version__ = "1.0.0"
__version__ = "1.1.0"

def get_session(account_id, role_name="OrganizationAccountAccessRole"):
"""Assumes a role in the target account to return a boto3 session."""
Expand All @@ -25,16 +28,24 @@ def get_session(account_id, role_name="OrganizationAccountAccessRole"):
return None

def main():
input_file = "remediate_tgw_dns.txt"
if not os.path.exists(input_file):
print(f"Error: {input_file} not found. Run assessment script first.")
parser = argparse.ArgumentParser(description="TGW VPC Attachment DNS Remediator")
parser.add_argument("--input", default="remediate_tgw_dns.txt", help="Target list file")
parser.add_argument("--rollback", action="store_true", help="Re-enable DNS Support instead of disabling it")
args = parser.parse_args()

if not os.path.exists(args.input):
print(f"Error: {args.input} not found. Run the assessment script first.")
sys.exit(1)

# Determine action based on flag
desired_state = "enable" if args.rollback else "disable"
action_label = "ROLLBACK (Enabling)" if args.rollback else "REMEDIATION (Disabling)"

print("-" * 100)
print(f"TGW DNS SUPPORT REMEDIATION SCRIPT | Version {__version__}")
print(f"TGW DNS SUPPORT {action_label} | Version {__version__}")
print("-" * 100)

with open(input_file, 'r') as f:
with open(args.input, 'r') as f:
lines = f.readlines()

for line in lines:
Expand All @@ -47,26 +58,27 @@ def main():
region = parts[1].strip()
attach_id = parts[2].strip()

print(f"Processing: Account {acc_id} | Region {region} | Attachment {attach_id}...")
print(f"Target: Account {acc_id} | Region {region} | Attachment {attach_id}")

session = get_session(acc_id)
if not session:
print(f" SKIPPING: Unable to access account {acc_id}")
continue

ec2 = session.client('ec2', region_name=region)
try:
# Perform the modification
# Perform the modification based on the desired state
response = ec2.modify_transit_gateway_vpc_attachment(
TransitGatewayAttachmentId=attach_id,
Options={'DnsSupport': 'disable'}
Options={'DnsSupport': desired_state}
)
state = response['TransitGatewayVpcAttachment']['State']
print(f" SUCCESS: Status is now '{state}'")
print(f" SUCCESS: DNS Support set to '{desired_state}'. Current state: {state}")
except Exception as e:
print(f" FAILED: {e}")

print("-" * 100)
print("Remediation Complete.")
print(f"{action_label} Complete.")

if __name__ == "__main__":
main()

0 comments on commit d688d75

Please sign in to comment.