# Create IAM Users

There are two users that we create. One user is used within our CI/CD platform to automatically build/upload Cloudformation templates and AMIs. The other user is used to programatically manage AWS organizations and access them programatically (client accounts).

# Asset Management

This user will be used with our CI/CD platform to automatically build/upload Cloudformation templates and AMIs. For staging, I created a user named staging-assets with the following inline policy named AssetManagement:

asset-management-policy.json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Packer",
            "Effect": "Allow",
            "Action": [
                "ec2:CopyImage",
                "ec2:CreateImage",
                "ec2:CreateSnapshot",
                "ec2:CreateTags",
                "ec2:CreateVolume",
                "ec2:DescribeImages",
                "ec2:DescribeImageAttribute",
                "ec2:DescribeInstanceStatus",
                "ec2:DescribeInstances",
                "ec2:DescribeRegions",
                "ec2:DescribeSecurityGroups",
                "ec2:DescribeSnapshots",
                "ec2:DescribeSubnets",
                "ec2:DescribeVolumes",
                "ec2:DescribeTags",
                "ec2:RegisterImage",
                "ec2:RunInstances",
                "ec2:GetPasswordData",
                "ec2:AttachVolume",
                "ec2:DeleteSnapshot",
                "ec2:DeleteVolume",
                "ec2:DeregisterImage",
                "ec2:DetachVolume",
                "ec2:ModifyImageAttribute",
                "ec2:ModifyInstanceAttribute",
                "ec2:ModifySnapshotAttribute",
                "ec2:StopInstances",
                "ec2:TerminateInstances",
                "ec2:CreateKeypair",
                "ec2:DeleteKeypair",
                "ec2:CreateSecurityGroup",
                "ec2:DeleteSecurityGroup",
                "ec2:AuthorizeSecurityGroupIngress"
            ],
            "Resource": "*"
        },
        {
            "Sid": "RainPutObject",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject"
            ],
            "Resource": [
                "arn:aws:s3:::jetrails-shared-assets-staging/cloudformation-templates/*"
            ]
        },
        {
            "Sid": "RainListBucket",
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::jetrails-shared-assets-staging"
            ]
        }
    ]
}

asset-management-policy.json
asset-management-policy.json 2.02KB

# API Access

I created a user named staging-api with the following inline policy named StagingApiAccess:

api-access-policy.json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "ListAccountsForOus",
            "Effect": "Allow",
            "Action": "organizations:ListAccountsForParent",
            "Resource": [
                "arn:aws:organizations::285269406112:root/o-t3sppsehs4/r-oezy",
                "arn:aws:organizations::285269406112:ou/o-t3sppsehs4/ou-oezy-zmb0bkr6",
                "arn:aws:organizations::285269406112:ou/o-t3sppsehs4/ou-oezy-iujea5me"
            ]
        },
        {
            "Sid": "MoveAccountAround",
            "Effect": "Allow",
            "Action": "organizations:MoveAccount",
            "Resource": [
                "arn:aws:organizations::285269406112:account/o-t3sppsehs4/*",
                "arn:aws:organizations::285269406112:root/o-t3sppsehs4/r-oezy",
                "arn:aws:organizations::285269406112:ou/o-t3sppsehs4/ou-oezy-zmb0bkr6",
                "arn:aws:organizations::285269406112:ou/o-t3sppsehs4/ou-oezy-iujea5me"
            ],
            "Condition": {
                "StringEquals": {
                    "aws:ResourceTag/AutoPilot": "true"
                }
            }
        },
        {
            "Sid": "CreateNewAccountWithProperTags",
            "Effect": "Allow",
            "Action": [
                "organizations:CreateAccount",
                "organizations:TagResource"
            ],
            "Resource": "arn:aws:organizations::285269406112:account/o-t3sppsehs4/*",
            "Condition": {
                "StringEquals": {
                    "aws:RequestTag/AutoPilot": "true"
                }
            }
        },
        {
            "Sid": "AllowTaggingOrganizationWhenActive",
            "Effect": "Allow",
            "Action": "organizations:TagResource",
            "Resource": "arn:aws:organizations::285269406112:account/o-t3sppsehs4/*",
            "Condition": {
                "StringLike": {
                    "aws:RequestTag/Organization": "*"
                }
            }
        },
        {
            "Sid": "AllowListingTagsForAccount",
            "Effect": "Allow",
            "Action": "organizations:ListTagsForResource",
            "Resource": "arn:aws:organizations::285269406112:account/o-t3sppsehs4/*"
        },
        {
            "Sid": "AssumeRoleForActiveCustomerAccounts",
            "Effect": "Allow",
            "Action": "sts:AssumeRole",
            "Resource": "arn:aws:iam::*:role/OrganizationAccountAccessRole",
            "Condition": {
                "ForAnyValue:StringLike": {
                    "aws:ResourceOrgPaths": "o-t3sppsehs4/r-oezy/ou-oezy-zmb0bkr6/*"
                }
            }
        },
        {
            "Sid": "ReadCloudFormationTemplates",
            "Effect": "Allow",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::jetrails-shared-assets-staging/cloudformation-templates/*"
        },
        {
            "Sid": "BillingS3BucketAccess",
            "Effect": "Allow",
            "Action": [
                "s3:GetBucketLocation",
                "s3:GetObject",
                "s3:ListBucket",
                "s3:ListBucketMultipartUploads",
                "s3:AbortMultipartUpload",
                "s3:PutObject",
                "s3:ListMultipartUploadParts"
            ],
            "Resource": [
                "arn:aws:s3:::jetrails-cost-and-usage-reports-staging",
                "arn:aws:s3:::jetrails-cost-and-usage-reports-staging/*"
            ]
        },
        {
            "Sid": "PullDataFromS3",
            "Effect": "Allow",
            "Action": [
                "glue:GetTable",
                "glue:GetPartitions",
                "glue:GetPartition"
            ],
            "Resource": "*"
        },
        {
            "Sid": "CalculateMonthlyInvoice",
            "Effect": "Allow",
            "Action": [
                "athena:StartQueryExecution",
                "athena:GetQueryResults"
            ],
            "Resource": "*"
        },
        {
            "Sid": "ResourceDiscovery",
            "Effect": "Allow",
            "Action": [
                "savingsplans:DescribeSavingsPlans",
                "es:DescribeReservedElasticsearchInstances",
                "ec2:DescribeReservedInstances",
                "rds:DescribeReservedDBInstances",
                "elasticache:DescribeReservedCacheNodes",
                "pricing:GetProducts"
            ],
            "Resource": "*"
        }
    ]
}

api-access-policy.json
api-access-policy.json 4.42KB

# Enabling Root Access Management

Visit https://us-east-1.console.aws.amazon.com/iam/home#/organizations/root-access-management and enable root access management. This is to prevent all our organizations from having their own root accounts. This makes everything easier to manage and more secure. New organizations will simply be created with no root account once this is enabled.