#
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:
{
"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"
]
}
]
}
#
API Access
I created a user named staging-api with the following inline policy named StagingApiAccess:
Note
Make sure the root OU, active OU, and retired OU is tagged with AutoPilot and with the value true. We explicity reference these tags in the policies we create below.
{
"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": "*"
}
]
}
#
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.