.claude/skills/aws-account-management/SKILL.md
Manage AWS accounts, organizations, IAM, and billing. Use when setting up AWS Organizations, managing IAM policies, controlling costs, or implementing multi-account strategies. Triggers on AWS Organizations, AWS IAM, AWS billing, Cost Explorer, SCPs, multi-account, AWS SSO, Identity Center.
npx skillsauth add Oratias07/CHAM-Agent aws-account-managementInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Manage AWS accounts, organizations, IAM, and billing effectively.
Root
├── Production OU
│ ├── Prod Account A
│ └── Prod Account B
├── Development OU
│ ├── Dev Account
│ └── Staging Account
├── Security OU
│ ├── Security Account
│ └── Log Archive Account
└── Sandbox OU
└── Sandbox Account
# Create organization (from management account)
aws organizations create-organization --feature-set ALL
# Create organizational unit
aws organizations create-organizational-unit \
--parent-id r-xxxx \
--name "Production"
# Create member account
aws organizations create-account \
--email [email protected] \
--account-name "Production Account"
# Move account to OU
aws organizations move-account \
--account-id 123456789012 \
--source-parent-id r-xxxx \
--destination-parent-id ou-xxxx-xxxxxxxx
// Deny leaving organization
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyLeaveOrg",
"Effect": "Deny",
"Action": "organizations:LeaveOrganization",
"Resource": "*"
}
]
}
// Require IMDSv2 (instance metadata)
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "RequireIMDSv2",
"Effect": "Deny",
"Action": "ec2:RunInstances",
"Resource": "arn:aws:ec2:*:*:instance/*",
"Condition": {
"StringNotEquals": {
"ec2:MetadataHttpTokens": "required"
}
}
}
]
}
// Region restriction
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyNonApprovedRegions",
"Effect": "Deny",
"NotAction": [
"iam:*",
"organizations:*",
"support:*",
"budgets:*"
],
"Resource": "*",
"Condition": {
"StringNotEquals": {
"aws:RequestedRegion": ["us-east-1", "us-west-2", "eu-west-1"]
}
}
}
]
}
// Prevent root user access
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyRootUser",
"Effect": "Deny",
"Action": "*",
"Resource": "*",
"Condition": {
"StringLike": {
"aws:PrincipalArn": "arn:aws:iam::*:root"
}
}
}
]
}
# Create SCP
aws organizations create-policy \
--name "DenyLeaveOrg" \
--type SERVICE_CONTROL_POLICY \
--content file://deny-leave-org.json
# Attach to OU
aws organizations attach-policy \
--policy-id p-xxxxxxxxxxxx \
--target-id ou-xxxx-xxxxxxxx
# Enable Identity Center
aws sso-admin create-instance
# Create permission set
aws sso-admin create-permission-set \
--instance-arn arn:aws:sso:::instance/ssoins-xxxxxxxx \
--name "AdministratorAccess" \
--session-duration "PT8H"
# Attach managed policy
aws sso-admin attach-managed-policy-to-permission-set \
--instance-arn arn:aws:sso:::instance/ssoins-xxxxxxxx \
--permission-set-arn arn:aws:sso:::permissionSet/ssoins-xxxxxxxx/ps-xxxxxxxx \
--managed-policy-arn arn:aws:iam::aws:policy/AdministratorAccess
// Developer permission set (inline policy)
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DeveloperAccess",
"Effect": "Allow",
"Action": [
"ec2:*",
"s3:*",
"lambda:*",
"dynamodb:*",
"cloudwatch:*",
"logs:*"
],
"Resource": "*"
},
{
"Sid": "DenyBillingAndIAM",
"Effect": "Deny",
"Action": [
"iam:CreateUser",
"iam:DeleteUser",
"iam:CreateAccessKey",
"aws-portal:*",
"budgets:*"
],
"Resource": "*"
}
]
}
// Least privilege policy example
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowS3BucketAccess",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject"
],
"Resource": "arn:aws:s3:::my-bucket/*",
"Condition": {
"StringEquals": {
"s3:x-amz-acl": "private"
}
}
},
{
"Sid": "AllowListBucket",
"Effect": "Allow",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::my-bucket",
"Condition": {
"StringLike": {
"s3:prefix": ["${aws:username}/*"]
}
}
}
]
}
// Cross-account role trust policy
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012:root"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"sts:ExternalId": "unique-external-id"
},
"Bool": {
"aws:MultiFactorAuthPresent": "true"
}
}
}
]
}
// Lambda execution role
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
// EC2 instance profile
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
# Generate credential report
aws iam generate-credential-report
aws iam get-credential-report --output text --query Content | base64 -d
# List unused access keys (last used > 90 days)
aws iam list-users --query 'Users[*].UserName' --output text | \
xargs -I {} aws iam list-access-keys --user-name {} \
--query 'AccessKeyMetadata[?Status==`Active`]'
# Get access key last used
aws iam get-access-key-last-used --access-key-id AKIAXXXXXXXX
# IAM Access Analyzer
aws accessanalyzer create-analyzer \
--analyzer-name my-analyzer \
--type ACCOUNT
# Create budget
aws budgets create-budget \
--account-id 123456789012 \
--budget '{
"BudgetName": "Monthly-Budget",
"BudgetLimit": {
"Amount": "1000",
"Unit": "USD"
},
"BudgetType": "COST",
"TimeUnit": "MONTHLY"
}' \
--notifications-with-subscribers '[
{
"Notification": {
"NotificationType": "ACTUAL",
"ComparisonOperator": "GREATER_THAN",
"Threshold": 80
},
"Subscribers": [
{
"SubscriptionType": "EMAIL",
"Address": "[email protected]"
}
]
}
]'
import boto3
from datetime import datetime, timedelta
client = boto3.client('ce')
# Get cost and usage
response = client.get_cost_and_usage(
TimePeriod={
'Start': (datetime.now() - timedelta(days=30)).strftime('%Y-%m-%d'),
'End': datetime.now().strftime('%Y-%m-%d')
},
Granularity='MONTHLY',
Metrics=['UnblendedCost'],
GroupBy=[
{'Type': 'DIMENSION', 'Key': 'SERVICE'},
{'Type': 'DIMENSION', 'Key': 'LINKED_ACCOUNT'}
]
)
# Get cost forecast
forecast = client.get_cost_forecast(
TimePeriod={
'Start': datetime.now().strftime('%Y-%m-%d'),
'End': (datetime.now() + timedelta(days=30)).strftime('%Y-%m-%d')
},
Metric='UNBLENDED_COST',
Granularity='MONTHLY'
)
print(f"Forecasted cost: ${forecast['Total']['Amount']}")
# Activate cost allocation tags
aws ce update-cost-allocation-tags-status \
--cost-allocation-tags-status '[
{"TagKey": "Environment", "Status": "Active"},
{"TagKey": "Project", "Status": "Active"},
{"TagKey": "CostCenter", "Status": "Active"}
]'
# Tag resources consistently
aws ec2 create-tags \
--resources i-1234567890abcdef0 \
--tags Key=Environment,Value=Production \
Key=Project,Value=WebApp \
Key=CostCenter,Value=Engineering
# Get Savings Plans recommendations
aws savingsplans describe-savings-plans-offering-rates \
--savings-plan-offering-ids xxxxxxxxx
# Get Reserved Instance recommendations
aws ce get-reservation-purchase-recommendation \
--service "Amazon Elastic Compute Cloud - Compute" \
--lookback-period-in-days THIRTY_DAYS \
--term-in-years ONE_YEAR \
--payment-option NO_UPFRONT
# Create organization trail
aws cloudtrail create-trail \
--name organization-trail \
--s3-bucket-name my-cloudtrail-bucket \
--is-organization-trail \
--is-multi-region-trail \
--enable-log-file-validation \
--kms-key-id alias/cloudtrail-key
# Start logging
aws cloudtrail start-logging --name organization-trail
# Log management events and S3 data events
aws cloudtrail put-event-selectors \
--trail-name organization-trail \
--event-selectors '[
{
"ReadWriteType": "All",
"IncludeManagementEvents": true,
"DataResources": [
{
"Type": "AWS::S3::Object",
"Values": ["arn:aws:s3:::sensitive-bucket/"]
}
]
}
]'
# Enable Config
aws configservice put-configuration-recorder \
--configuration-recorder name=default,roleARN=arn:aws:iam::123456789012:role/config-role
# Deploy managed rule
aws configservice put-config-rule \
--config-rule '{
"ConfigRuleName": "s3-bucket-public-read-prohibited",
"Source": {
"Owner": "AWS",
"SourceIdentifier": "S3_BUCKET_PUBLIC_READ_PROHIBITED"
}
}'
# Organization Config rules
aws configservice put-organization-config-rule \
--organization-config-rule-name "org-s3-bucket-public-read-prohibited" \
--organization-managed-rule-metadata '{
"RuleIdentifier": "S3_BUCKET_PUBLIC_READ_PROHIBITED"
}'
# conformance-pack.yaml
Parameters:
S3BucketName:
Type: String
Resources:
S3BucketPublicReadProhibited:
Type: AWS::Config::ConfigRule
Properties:
ConfigRuleName: s3-bucket-public-read-prohibited
Source:
Owner: AWS
SourceIdentifier: S3_BUCKET_PUBLIC_READ_PROHIBITED
IAMRootAccessKeyCheck:
Type: AWS::Config::ConfigRule
Properties:
ConfigRuleName: iam-root-access-key-check
Source:
Owner: AWS
SourceIdentifier: IAM_ROOT_ACCESS_KEY_CHECK
MFAEnabledForIAMConsoleAccess:
Type: AWS::Config::ConfigRule
Properties:
ConfigRuleName: mfa-enabled-for-iam-console-access
Source:
Owner: AWS
SourceIdentifier: MFA_ENABLED_FOR_IAM_CONSOLE_ACCESS
# providers.tf
provider "aws" {
alias = "management"
region = "us-east-1"
}
provider "aws" {
alias = "production"
region = "us-east-1"
assume_role {
role_arn = "arn:aws:iam::${var.prod_account_id}:role/TerraformRole"
}
}
provider "aws" {
alias = "development"
region = "us-east-1"
assume_role {
role_arn = "arn:aws:iam::${var.dev_account_id}:role/TerraformRole"
}
}
# Create resources in specific accounts
resource "aws_s3_bucket" "prod_bucket" {
provider = aws.production
bucket = "my-prod-bucket"
}
resource "aws_s3_bucket" "dev_bucket" {
provider = aws.development
bucket = "my-dev-bucket"
}
# modules/account/main.tf
resource "aws_organizations_account" "account" {
name = var.account_name
email = var.account_email
parent_id = var.organizational_unit_id
role_name = "OrganizationAccountAccessRole"
tags = {
Environment = var.environment
ManagedBy = "Terraform"
}
}
resource "aws_iam_role" "terraform_role" {
provider = aws.new_account
name = "TerraformRole"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Principal = {
AWS = "arn:aws:iam::${var.management_account_id}:root"
}
Action = "sts:AssumeRole"
}
]
})
}
## Account Security
- [ ] MFA enabled on root account
- [ ] Root account access keys deleted
- [ ] Root account email is distribution list
- [ ] Strong password policy configured
- [ ] CloudTrail enabled in all regions
- [ ] GuardDuty enabled
- [ ] Security Hub enabled
- [ ] Config enabled with rules
## Organization Security
- [ ] SCPs restrict dangerous actions
- [ ] SCPs enforce region restrictions
- [ ] SCPs require encryption
- [ ] Log archive account isolated
- [ ] Security account isolated
- [ ] Cross-account access uses roles (not users)
## IAM Security
- [ ] No long-lived access keys
- [ ] IAM Access Analyzer enabled
- [ ] Unused credentials rotated/removed
- [ ] Permission boundaries on delegated admins
- [ ] Service-linked roles used where possible
## Cost Management
- [ ] Budgets configured with alerts
- [ ] Cost allocation tags active
- [ ] Savings Plans evaluated
- [ ] Unused resources cleaned up
- [ ] Right-sizing recommendations reviewed
development
Build accessible web applications following WCAG guidelines. Use when implementing ARIA patterns, keyboard navigation, screen reader support, or ensuring accessibility compliance. Triggers on accessibility, a11y, WCAG, ARIA, screen reader, keyboard navigation.
devops
Deploy and configure applications on Vercel. Use when deploying Next.js apps, configuring serverless functions, setting up edge functions, or managing Vercel projects. Triggers on Vercel, deploy, serverless, edge function, Next.js deployment.
development
Build consistent design systems with tokens, components, and theming. Use when creating component libraries, implementing design tokens, building theme systems, or ensuring design consistency. Triggers on design system, design tokens, component library, theming, dark mode.
development
Generate images with Google's Nano Banana Pro (Gemini 3 Pro Image). Use when generating AI images via Gemini API, creating professional visuals, or building image generation features. Triggers on Nano Banana Pro, Gemini 3 Pro Image, gemini-3-pro-image-preview, Google image generation.