From 5e7d0fdc66045dc22eee697d29b88c08ab9e35e9 Mon Sep 17 00:00:00 2001 From: Thirumalesh Aaraveti Date: Wed, 11 Sep 2024 11:25:14 +0530 Subject: [PATCH] Create the cloud-governance infra: User, Policy, Bucket --- .../CloudGovernanceDeletePolicy.json | 136 ++++++++------- .../CloudGovernanceInfra.tar | Bin 0 -> 24064 bytes .../CloudGovernanceReadPolicy.json | 85 ++++++---- iam/clouds/aws/CloudGovernanceInfra/README.md | 44 +++++ .../aws/CloudGovernanceInfra/create_infra.sh | 158 ++++++++++++++++++ jenkins/tenant/aws/README.md | 20 ++- 6 files changed, 335 insertions(+), 108 deletions(-) rename iam/clouds/aws/{ => CloudGovernanceInfra}/CloudGovernanceDeletePolicy.json (84%) create mode 100644 iam/clouds/aws/CloudGovernanceInfra/CloudGovernanceInfra.tar rename iam/clouds/aws/{ => CloudGovernanceInfra}/CloudGovernanceReadPolicy.json (79%) create mode 100644 iam/clouds/aws/CloudGovernanceInfra/README.md create mode 100755 iam/clouds/aws/CloudGovernanceInfra/create_infra.sh diff --git a/iam/clouds/aws/CloudGovernanceDeletePolicy.json b/iam/clouds/aws/CloudGovernanceInfra/CloudGovernanceDeletePolicy.json similarity index 84% rename from iam/clouds/aws/CloudGovernanceDeletePolicy.json rename to iam/clouds/aws/CloudGovernanceInfra/CloudGovernanceDeletePolicy.json index f2fa18701..98cc39a8d 100644 --- a/iam/clouds/aws/CloudGovernanceDeletePolicy.json +++ b/iam/clouds/aws/CloudGovernanceInfra/CloudGovernanceDeletePolicy.json @@ -6,7 +6,13 @@ "Effect": "Allow", "Action": [ "ce:GetCostAndUsage", - "ce:GetCostForecast" + "ce:GetCostForecast", + "tag:GetResources", + "tag:TagResources", + "support:DescribeTrustedAdvisorCheckResult", + "support:DescribeTrustedAdvisorChecks", + "resource-explorer-2:ListViews", + "resource-explorer-2:Search" ], "Resource": "*" }, @@ -39,52 +45,49 @@ "Sid": "EC2ResourceLevel", "Effect": "Allow", "Action": [ - "ec2:DeregisterImage", - "ec2:DeleteSubnet", + "autoscaling:DescribeAutoScalingGroups", + "autoscaling:DescribeLaunchConfigurations", + "ec2:AssociateDhcpOptions", + "ec2:DeleteDhcpOptions", + "ec2:DeleteInternetGateway", + "ec2:DeleteNatGateway", + "ec2:DeleteNetworkAcl", + "ec2:DeleteNetworkInterface", + "ec2:DeleteRouteTable", + "ec2:DeleteSecurityGroup", "ec2:DeleteSnapshot", - "ec2:DescribeAddresses", - "ec2:DescribeInstances", + "ec2:DeleteSubnet", + "ec2:DeleteVolume", + "ec2:DeleteVpc", "ec2:DeleteVpcEndpoints", "ec2:DeleteVpcPeeringConnection", - "autoscaling:DescribeLaunchConfigurations", - "ec2:DescribeRegions", - "ec2:CreateImage", - "ec2:CreateVpc", + "ec2:DeregisterImage", + "ec2:DescribeAddresses", "ec2:DescribeDhcpOptions", - "ec2:DescribeSnapshots", - "ec2:DeleteRouteTable", + "ec2:DescribeImages", + "ec2:DescribeInstanceTypes", + "ec2:DescribeInstances", "ec2:DescribeInternetGateways", - "ec2:DeleteVolume", - "ec2:DescribeNetworkInterfaces", - "autoscaling:DescribeAutoScalingGroups", - "ec2:DescribeVolumes", - "ec2:DeleteInternetGateway", + "ec2:DescribeNatGateways", "ec2:DescribeNetworkAcls", + "ec2:DescribeNetworkInterfaces", + "ec2:DescribeRegions", + "ec2:DescribeReservedInstances", "ec2:DescribeRouteTables", - "ec2:DeleteNetworkAcl", - "ec2:ReleaseAddress", - "ec2:AssociateDhcpOptions", - "ec2:TerminateInstances", - "ec2:DetachNetworkInterface", + "ec2:DescribeSecurityGroups", + "ec2:DescribeSnapshots", + "ec2:DescribeSubnets", "ec2:DescribeTags", + "ec2:DescribeVolumes", + "ec2:DescribeVpcEndpoints", "ec2:DescribeVpcPeeringConnections", - "ec2:ModifyNetworkInterfaceAttribute", - "ec2:DeleteNetworkInterface", + "ec2:DescribeVpcs", "ec2:DetachInternetGateway", - "ec2:DescribeNatGateways", - "ec2:StopInstances", + "ec2:DetachNetworkInterface", "ec2:DisassociateRouteTable", - "ec2:DescribeSecurityGroups", - "ec2:RevokeSecurityGroupIngress", - "ec2:DescribeImages", - "ec2:DescribeVpcs", - "ec2:DeleteSecurityGroup", - "ec2:DescribeInstanceTypes", - "ec2:DeleteDhcpOptions", - "ec2:DeleteNatGateway", - "ec2:DescribeVpcEndpoints", - "ec2:DeleteVpc", - "ec2:DescribeSubnets" + "ec2:ModifyNetworkInterfaceAttribute", + "ec2:ReleaseAddress", + "ec2:RevokeSecurityGroupIngress" ], "Resource": "*" }, @@ -95,7 +98,8 @@ "elasticloadbalancing:DeleteLoadBalancer", "elasticloadbalancing:DescribeTags", "elasticloadbalancing:AddTags", - "elasticloadbalancing:DescribeLoadBalancers" + "elasticloadbalancing:DescribeLoadBalancers", + "elasticloadbalancing:RemoveTags" ], "Resource": "*" }, @@ -103,32 +107,28 @@ "Sid": "IAM", "Effect": "Allow", "Action": [ - "iam:GetRole", - "iam:DeleteAccessKey", - "iam:DeleteGroup", - "iam:TagRole", + "iam:DeleteInstanceProfile", + "iam:DeletePolicy", + "iam:DeleteRole", + "iam:DeleteRolePolicy", "iam:DeleteUserPolicy", - "iam:ListRoles", - "iam:DeleteUser", - "iam:ListUserPolicies", - "iam:CreateUser", - "iam:TagUser", - "sts:AssumeRole", - "iam:RemoveUserFromGroup", - "iam:GetUserPolicy", - "iam:ListAttachedRolePolicies", - "iam:ListUsers", + "iam:DetachRolePolicy", + "iam:GetRole", "iam:GetUser", + "iam:GetUserPolicy", "iam:ListAccessKeys", - "iam:ListRolePolicies", "iam:ListAccountAliases", - "iam:DeleteRole", - "iam:DetachRolePolicy", - "iam:DeletePolicy", - "iam:DeleteRolePolicy", + "iam:ListAttachedRolePolicies", "iam:ListInstanceProfilesForRole", + "iam:ListRolePolicies", + "iam:ListRoles", + "iam:ListUserPolicies", + "iam:ListUsers", "iam:RemoveRoleFromInstanceProfile", - "sts:GetCallerIdentity" + "iam:TagRole", + "iam:TagUser", + "iam:UntagRole", + "iam:UntagUser" ], "Resource": "*" }, @@ -142,17 +142,16 @@ "Sid": "S3Bucket", "Effect": "Allow", "Action": [ - "s3:PutObject", + "s3:DeleteBucket", + "s3:DeleteObject", + "s3:GetBucketLocation", + "s3:GetBucketTagging", "s3:GetObject", "s3:ListAllMyBuckets", - "s3:CreateBucket", "s3:ListBucket", + "s3:PutObject", "s3:PutObjectTagging", - "s3:DeleteObject", - "s3:DeleteBucket", - "s3:putBucketTagging", - "s3:GetBucketTagging", - "s3:GetBucketLocation" + "s3:putBucketTagging" ], "Resource": "*" }, @@ -173,6 +172,15 @@ "cloudwatch:GetMetricData" ], "Resource": "*" + }, + { + "Sid": "RDS", + "Effect": "Allow", + "Action": [ + "rds:AddTagsToResource", + "rds:DescribeDBInstances" + ], + "Resource": "*" } ] } diff --git a/iam/clouds/aws/CloudGovernanceInfra/CloudGovernanceInfra.tar b/iam/clouds/aws/CloudGovernanceInfra/CloudGovernanceInfra.tar new file mode 100644 index 0000000000000000000000000000000000000000..fa2c7bd08ebf4c2eab7e6f8783bd461afe3d222e GIT binary patch literal 24064 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 --s3-bucket-name [--policy-type ]" + echo "" + echo "Options:" + echo " --username Specify the IAM username to create." + echo " --policy-type (Optional) Specify the policy type to create and attach. Supported Values: read, delete." + echo " --s3-bucket-name (Optional) Specify the S3 bucket name to create." + echo " --help Display this help message." + echo "" + echo "Example:" + echo " $0 --username my-username --policy-type read --s3-bucket-name my-bucket" + echo " $0 --username my-username --s3-bucket-name my-bucket" + exit 0 +} + +to_title_case() { + echo "$1" | awk '{print toupper(substr($0,1,1)) tolower(substr($0,2))}' +} + +delete_user() { + aws iam delete-user --user-name "$1" 1>/dev/null + echo "Deleted IAM User $1 due to failures." +} + +delete_policy() { + aws iam delete-policy --policy-arn "$1" 1>/dev/null + echo "Deleted IAM Policy $1 due to failures." +} + +delete_bucket() { + aws s3 rb "s3://$1" --force 1>/dev/null + echo "Deleted S3 bucket $1 due to failures." +} + +create_bucket() { + if ! aws s3api create-bucket --bucket "$1" --region "$AWS_DEFAULT_REGION" --create-bucket-configuration LocationConstraint="$AWS_DEFAULT_REGION" 1>/dev/null; then + echo "Failed to create S3 bucket $1." + delete_user "$2" + if [ -n "$3" ]; then + delete_policy "$3" + fi + exit 1 + fi + echo "S3 bucket $1 created successfully." +} + +create_access_key() { + access_key_json=$(aws iam create-access-key --user-name "$1" --query 'AccessKey.[AccessKeyId,SecretAccessKey]' --output json) + if [ $? -ne 0 ]; then + echo "Failed to create access key for user $1." + delete_user "$1" + if [ -n "$3" ]; then + delete_bucket "$2" + fi + if [ -n "$3" ]; then + delete_policy "$3" + fi + exit 1 + fi + + access_key_id=$(echo "$access_key_json" | jq -r '.[0]') + secret_access_key=$(echo "$access_key_json" | jq -r '.[1]') + + echo "Access Key ID: $access_key_id" + echo "Secret Access Key: $secret_access_key" +} + +create_user() { + if ! aws iam create-user --user-name "$1" --tags "Key=User,Value=$1" 1>/dev/null; then + echo "Failed to create user $1." + exit 1 + fi + echo "User $1 created successfully." +} + + + +while [[ "$#" -gt 0 ]]; do + case $1 in + --username) username="$2"; shift ;; + --policy-type) policy_type="$2"; shift ;; + --s3-bucket-name) s3_bucket_name="$2"; shift ;; + --help) show_help=true ;; + *) echo "Unknown parameter passed: $1"; show_help ;; + esac + shift +done + +if [ "$show_help" = true ]; then + show_help +fi + + +if [ -z "$username" ] ; then + echo "Error: --username and --s3-bucket-name are required." + show_help +fi + +if [ -n "$policy_type" ]; then + case "$(to_title_case "$policy_type")" in + Read|Delete) policy_type=$(to_title_case "$policy_type") ;; + *) echo "Error: Unsupported policy type '$policy_type'. Supported values are: Read, Delete."; exit 1 ;; + esac +fi + +policy_document="./CloudGovernance${policy_type}Policy.json" +account_id=$(aws sts get-caller-identity --query 'Account' --output text) +if [ $? -ne 0 ]; then + echo "Failed to retrieve AWS account ID." + exit 1 +fi +echo "AWS Account ID: $account_id" + +if [ -n "$account_id" ]; then + sed -i '' -e "s/account_id/${account_id}/g" "$policy_document" +fi + +create_user "$username" + +if [ -n "$policy_type" ]; then + policy_name="CloudGovernance${policy_type}" + + if [ ! -f "$policy_document" ]; then + echo "Error: Policy document file $policy_document does not exist." + delete_user "$username" + exit 1 + fi + + policy_arn=$(aws iam create-policy --policy-name "$policy_name" --policy-document "file://$policy_document" --query 'Policy.Arn' --output text) + if [ $? -ne 0 ]; then + echo "Failed to create policy $policy_name." + delete_user "$username" + exit 1 + fi + echo "Policy $policy_name created successfully with ARN $policy_arn." + + if ! aws iam attach-user-policy --user-name "$username" --policy-arn "$policy_arn"; then + echo "Failed to attach policy $policy_name to user $username." + delete_policy "$policy_arn" + delete_user "$username" + exit 1 + fi + echo "Policy $policy_name attached to user $username successfully." +fi +if [ -n "$s3_bucket_name" ]; then + create_bucket "$s3_bucket_name" "$username" "$policy_arn" +fi + + +create_access_key "$username" "$s3_bucket_name" "$policy_arn" diff --git a/jenkins/tenant/aws/README.md b/jenkins/tenant/aws/README.md index afcae3a85..eb58efbbf 100644 --- a/jenkins/tenant/aws/README.md +++ b/jenkins/tenant/aws/README.md @@ -1,12 +1,14 @@ # How to run cloud-governance on Tenant Accounts Steps -1. Create AWS User and attach user by [CloudGovernanceDeletePolicy.json](../../../iam/clouds/aws/CloudGovernanceDeletePolicy.json). [ Note: Replace account_id with actual account id] -2. Create S3 bucket -3. Add kind secret-text to jenkins with below naming conventions - 1. ${account_name}-aws-access-key-id - 2. ${account_name}-aws-secret-key-id - 3. ${account_name}-s3-bucket -4. Create folder named that you want to run the cloud-governance policies and copy the file in templates. -5. Add account_name to account variable in this [PolicyJenkinsfileDaily](../aws/template/PolicyJenkinsfileDaily) and [TaggingJenkinsfileHourly](../aws/template/TaggingJenkinsfileHourly). -6. Create two Jenkins jobs by using this two Jenkinsfile + +1. Create IAM User with Read/Delete Permissions and create S3 bucket. + 1. Follow the instructions [README.md](..%2F..%2F..%2Fiam%2Fclouds%2Faws%2FCloudGovernanceInfra%2FREADME.md). +2. Add kind secret-text to jenkins with below naming conventions + 1. ${account_name}-aws-access-key-id + 2. ${account_name}-aws-secret-key-id + 3. ${account_name}-s3-bucket +3. Create folder named that you want to run the cloud-governance policies and copy the file in templates. +4. Add account_name to account variable in this [PolicyJenkinsfileDaily](../aws/template/PolicyJenkinsfileDaily) + and [TaggingJenkinsfileHourly](../aws/template/TaggingJenkinsfileHourly). +5. Create two Jenkins jobs by using this two Jenkinsfile