Skip to content

Instantly share code, notes, and snippets.

@coingraham
Forked from nitrocode/README.md
Created January 16, 2020 15:52
Show Gist options
  • Save coingraham/3ca0b569b5f2860260b92674bdf348c0 to your computer and use it in GitHub Desktop.
Save coingraham/3ca0b569b5f2860260b92674bdf348c0 to your computer and use it in GitHub Desktop.
Cloud custodian iam policy in terraform

CloudCustodian IAM Policy

Extracts perms from cloud-custodian repo, sanitizes extracted data, and transforms into terraform

Dependency is ripgrep and git which can be installed using brew

brew install rg git

The code will

  1. search for permissions = (get this data) over multiline
  2. print only the captured group
  3. remove the file names from rg output
  4. make all quotes single quotes
  5. insert a new line in between single quoted strings
  6. make all quotes double quotes
  7. remove leading whitespace and empty lines
  8. remove any lines that don't begin with a quote
  9. remove all quotes
  10. remove all commas
  11. sort output
  12. only return unique values

Rest of the magic is in python

Usage

  1. Install ripgrep and git
  2. Download extract-perms.sh and convert-extracted-cloud-custodian-perms-to-terraform.py
  3. Run extract-perms.sh

The output terraform will be saved in cloud-custodian-iam-policy.tf and the list of perms will be saved in perms.txt.

locals {
name = "cloud-custodian"
tags = {
application = local.name
}
}
# source: https://github.com/cloud-custodian/cloud-custodian/issues/1693
# command: iam-policy-json-to-terraform < cloud-custodian-iam-policy.json | pbcopy
data "aws_iam_policy_document" "default" {
statement {
sid = ""
effect = "Allow"
resources = ["*"]
actions = [
"health:DescribeEvents",
"health:DescribeAffectedEntities",
"health:DescribeEventDetails",
]
}
statement {
sid = ""
effect = "Allow"
resources = ["*"]
actions = [
"lambda:DeleteFunction",
"lambda:GetPolicy",
"lambda:RemovePermission",
"lambda:TagResource",
"lambda:UntagResource",
"lambda:InvokeFunction",
]
}
statement {
sid = ""
effect = "Allow"
resources = ["*"]
actions = [
"cloudtrail:CreateTrail",
"cloudtrail:DescribeTrails",
"cloudtrail:GetEventSelectors",
"cloudtrail:GetTrailStatus",
"config:DescribeDeliveryChannels",
"config:DescribeConfigurationRecorders",
"config:DescribeConfigurationRecorderStatus",
"config:GetResourceConfigHistory",
"support:CreateCase",
"support:DescribeTrustedAdvisorCheckResult",
"support:RefreshTrustedAdvisorCheck",
"shield:CreateSubscription",
"shield:DescribeSubscription",
"shield:DeleteSubscription",
]
}
statement {
sid = ""
effect = "Allow"
resources = ["*"]
actions = [
"ec2:AssociateIamInstanceProfile",
"ec2:AuthorizeSecurityGroupIngress",
"ec2:AuthorizeSecurityGroupEgress",
"ec2:CreateSnapshot",
"ec2:CreateTags",
"ec2:CopySnapshot",
"ec2:CreateSnapshot",
"ec2:DeleteVolume",
"ec2:DeleteNatGateway",
"ec2:DeleteSecurityGroup",
"ec2:DeleteSnapshot",
"ec2:DeleteTags",
"ec2:DeregisterImage",
"ec2:DescribeImages",
"ec2:DescribeInstanceAttribute",
"ec2:DescribeInstances",
"ec2:DescribeInstanceStatus",
"ec2:DescribeFlowLogs",
"ec2:DescribePrefixLists",
"ec2:DescribeRouteTables",
"ec2:DescribeStaleSecurityGroups",
"ec2:DescribeSecurityGroups",
"ec2:DescribeSubnets",
"ec2:DescribeTags",
"ec2:DescribeVolumes",
"ec2:DescribeVpcs",
"ec2:DisassociateIamInstanceProfile",
"ec2:DescribeSnapshotAttribute",
"ec2:DescribeSnapshots",
"ec2:DetachVolume",
"ec2:ModifyVolumeAttribute",
"ec2:ModifyInstanceAttribute",
"ec2:ModifyNetworkInterfaceAttribute",
"ec2:ResetImageAttribute",
"ec2:RevokeSecurityGroupIngress",
"ec2:RevokeSecurityGroupEgress",
"ec2:StartInstances",
"ec2:StopInstances",
"ec2:TerminateInstances",
]
}
statement {
sid = ""
effect = "Allow"
resources = ["*"]
actions = [
"tag:TagResources",
"tag:UntagResources",
]
}
statement {
sid = ""
effect = "Allow"
resources = ["*"]
actions = [
"waf-regional:AssociateWebACL",
"waf-regional:ListResourcesForWebACL",
"waf-regional:ListWebACLs",
]
}
statement {
sid = ""
effect = "Allow"
resources = ["*"]
actions = [
"elasticloadbalancing:AddTags",
"elasticloadbalancing:ApplySecurityGroupsToLoadBalancer",
"elasticloadbalancing:CreateLoadBalancerPolicy",
"elasticloadbalancing:DeleteLoadBalancer",
"elasticloadbalancing:DescribeLoadBalancerAttributes",
"elasticloadbalancing:DescribeLoadBalancerPolicies",
"elasticloadbalancing:DescribeListeners",
"elasticloadbalancing:DescribeTargetGroups",
"elasticloadbalancing:ModifyLoadBalancerAttributes",
"elasticloadbalancing:ModifyListener",
"elasticloadbalancing:RemoveTags",
"elasticloadbalancing:SetLoadBalancerPoliciesOfListener",
]
}
statement {
sid = ""
effect = "Allow"
resources = ["*"]
actions = [
"autoscaling:CreateOrUpdateTags",
"autoscaling:DescribeLaunchConfigurations",
"autoscaling:DeleteAutoScalingGroup",
"autoscaling:DeleteLaunchConfiguration",
"autoscaling:DeleteTags",
"autoscaling:UpdateAutoScalingGroup",
"autoscaling:SuspendProcesses",
"autoscaling:ResumeProcesses",
]
}
statement {
sid = ""
effect = "Allow"
resources = ["*"]
actions = [
"cloudfront:UpdateDistribution",
"cloudfront:GetDistributionConfig",
"cloudfront:GetStreamingDistributionConfig",
"cloudfront:UpdateStreamingDistribution",
"waf:ListWebACLs",
]
}
statement {
sid = ""
effect = "Allow"
resources = ["*"]
actions = [
"cloudwatch:DeleteAlarms",
"cloudwatch:DescribeAlarmsForMetric",
"cloudwatch:GetMetricStatistics",
"cloudWatch:PutMetricData",
"logs:DeleteLogGroup",
"logs:DescribeLogStreams",
"logs:PutRetentionPolicy",
]
}
statement {
sid = ""
effect = "Allow"
resources = ["*"]
actions = [
"dynamodb:DeleteTable",
"dynamodb:ListTagsOfResource",
"dynamodb:TagResource",
"dynamodb:UntagResource",
]
}
statement {
sid = ""
effect = "Allow"
resources = ["*"]
actions = [
"ecr:GetRepositoryPolicy",
"ecr:SetRepositoryPolicy",
]
}
statement {
sid = ""
effect = "Allow"
resources = ["*"]
actions = [
"elasticfilesystem:DeleteFileSystem",
"elasticfilesystem:DeleteMountTarget",
"elasticfilesystem:DescribeMountTargets",
]
}
statement {
sid = ""
effect = "Allow"
resources = ["*"]
actions = [
"elasticache:CreateSnapshot",
"elasticache:ListTagsForResource",
"elasticache:ModifyReplicationGroup",
"elasticache:DeleteCacheCluster",
"elasticache:DeleteReplicationGroup",
"elasticache:DeleteSnapshot",
]
}
statement {
sid = ""
effect = "Allow"
resources = ["*"]
actions = [
"sqs:DeleteQueue",
"sqs:GetQueueAttributes",
"sqs:SetQueueAttributes",
]
}
statement {
sid = ""
effect = "Allow"
resources = ["*"]
actions = [
"sns:GetTopicAttributes",
"sns:SetTopicAttributes",
]
}
statement {
sid = ""
effect = "Allow"
resources = ["*"]
actions = ["es:DeleteElasticsearchDomain"]
}
statement {
sid = ""
effect = "Allow"
resources = ["*"]
actions = [
"rds:AddTagsToResource",
"rds:CopyDBSnapshot",
"rds:CreateDBSnapshot",
"rds:DeleteDBInstance",
"rds:DeleteDBSnapshot",
"rds:DescribeDBEngineVersions",
"rds:DescribeDBInstances",
"rds:DescribeDBParameters",
"rds:DescribeDBSnapshotAttributes",
"rds:DescribeDBSnapshots",
"rds:ModifyDBCluster",
"rds:ModifyDBInstance",
"rds:ModifyDBParameterGroup",
"rds:RemoveTagsFromResource",
"rds:RebootDBInstance",
]
}
statement {
sid = ""
effect = "Allow"
resources = ["*"]
actions = [
"sts:AssumeRole",
"iam:DeleteAccessKey",
"iam:GenerateCredentialReport",
"iam:GetAccountSummary",
"iam:GetAccountPasswordPolicy",
"iam:GetCredentialReport",
"iam:GetGroup",
"iam:ListAccessKeys",
"iam:ListAccountAliases",
"iam:ListAttachedUserPolicies",
"iam:ListAttachedRolePolicies",
"iam:ListPolicyVersions",
"iam:ListGroupPolicies",
"iam:ListGroupsForUser",
"iam:ListMfaDevices",
"iam:ListPolicies",
"iam:ListRolePolicies",
"iam:ListVirtualMFADevices",
"iam:UpdateAccessKey",
]
}
statement {
sid = ""
effect = "Allow"
resources = ["*"]
actions = [
"s3:DeleteBucketPolicy",
"s3:DeleteBucketWebsite",
"s3:ListAllMyBuckets",
"s3:ListBucket",
"s3:GetBucketPolicy",
"s3:GetObject",
"s3:GetBucketNotification",
"s3:GetBucketPolicy",
"s3:GetInventoryConfiguration",
"s3:PutBucketAcl",
"s3:PutBucketPolicy",
"s3:PutBucketVersioning",
"s3:PutBucketLogging",
"s3:PutBucketNotification",
"s3:PutInventoryConfiguration",
"s3:PutObject",
]
}
statement {
sid = ""
effect = "Allow"
resources = ["*"]
actions = [
"cloudtrail:DescribeTrails",
"cloudtrail:GetEventSelectors",
]
}
}
data "aws_iam_policy_document" "assume_role_policy" {
statement {
actions = ["sts:AssumeRole"]
principals {
type = "Service"
identifiers = ["lambda.amazonaws.com"]
}
}
}
resource "aws_iam_role_policy" "default" {
name = local.name
role = local.name
policy = data.aws_iam_policy_document.default.json
}
resource "aws_iam_role" "default" {
name = local.name
assume_role_policy = data.aws_iam_policy_document.assume_role_policy.json
tags = local.tags
}
import sys
def statement(sid, actions):
print('')
print(' statement {')
print(' sid = "{0}"'.format(sid))
print(' effect = "Allow"')
print(' resources = ["*"]')
print('')
print(' actions = [')
for action in actions:
print(' "{0}",'.format(action))
print(' ]')
print(' }')
print('data "aws_iam_policy_document" "default" {')
actions = []
last_sline = None
for stdline in sys.stdin:
line = stdline
sline = line.split(':')
if last_sline and sline[0] != last_sline[0]:
statement(last_sline[0], actions)
actions = [line.rstrip('\n')]
else:
actions.append(line.rstrip('\n'))
last_sline = sline
statement(last_sline[0], actions)
print('}')
# get code
git clone git@github.com:cloud-custodian/cloud-custodian.git
cd cloud-custodian
# extract and transform
rg 'permissions\s+=\s+\((.*?)\)' \
--multiline-dotall --multiline -r '$1' -I | \
tr '"' "'" | \
sed $'s/\', \'/\', \\\n\'/g' | \
tr "'" '"' | \
awk '{$1=$1};1' | \
sed '/^[[:space:]]*$/d' | \
grep -e '^"' | \
tr -d '"' | \
tr -d ',' | \
tr '[:upper:]' '[:lower:]' | \
sort | \
uniq > perms.txt
# run python script to convert to terraform
cat perms.txt | python convert-extracted-cloud-custodian-perms-to-terraform.py > cloud-custodian-iam-policy.tf
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment