We (Blackbird Cloud) have deployed many AWS cloud environment for our clients. We use this repository as a boilerplate for our cloud deployment.
This Repository includes:
- AWS Cloudformation Stack templates to bootstrap your account after creation.
- Terragrunt and Terraform resources to configure the following services:
- AWS Organizations
- AWS IAM Identity Center
- AWS Cloudformation StackSets
- AWS KMS key for Terraform state encryption.
- AWS S3 bucket for Terraform state storage.
- AWS KMS key for audit log encryption.
- AWS S3 bucket for audit log collection.
- AWS Cloudtrial organization configuration.
- GitOps (GitHub Action) pipeline
-
Create an AWS Account here, name it management. Select the region you would like to deploy your resources to, write down the region and account id.
-
Navigate to Security Credentials, and register a MFA device for your root account.
-
Navigate to your Account page in the Billing console, and enable acces for IAM users.
-
Select the region in which you would like to create your AWS resources.
-
Navigate to AWS Cloudformation => Stacks, and manually deploy the following stack templates in the specified order:
stacks/github-oidc-provider.yaml,stacks/github-oidc-role.yaml,stacks/terraform-state.yaml, andstacks/iam-role.yaml.- For the Github oidc role stack, fill in
GitHubIdentityProviderArnwith the ARN of the IDP created on thegithub-oidc-providerstack. Fill inSubjectClaimFilterswith the following data relating to your infra reporepo:YOUR_GITHUB_ORGANIZATION/YOUR_GITHUB_REPOSITORY_NAME:ref:refs/heads/BRANCH_NAMEwe advise to deploy usemainas branch name. This is nessecary to make sure that only GitHub Actions that run on the main branch are allowed to plan and apply changes on AWS. Make sure to protect your main branch, as it will receive AdministratorAccess on your AWS cloud. Once the stack has been created, navigate to its resources, and note down the arn of created IAM role. ForGitHubActionsJumpRoleNameuse the same name as you will on theiam-rolestackRoleNameparameter. - For the
terraform-statestack, fill inGithubActionsRoleArnwith the role ARN created in thegithub-oidc-rolestack. Once the terraform state stack has been created, note down the bucket name, it will be used as the state bucket for the next steps. - For the
iam-rolestack, fill inPrincipalARNwith the role ARN created in thegithub-oidc-rolestack. Make sure to write down the Role name, and configure it inglobals.hclatgithub_role_name. UnderManagedPolicyARNsone can configurearn:aws:iam::aws:policy/AdministratorAccess.
- For the Github oidc role stack, fill in
-
Create 2 variables on GitHub -> Settings -> Secrets and variables -> Actions -> Variables
AWS_IAM_ROLE: fill inIAM Role ARNcreated by github-oidc-role stackAWS_REGION: fill in your selected AWS region.
-
On
.github/workflows/aws_deployment.ymlupdate all occurences of<my-project-name>to your github repository name, line 46. -
On
global.hclenter all the required information at theEnter manuallyblock. -
On
cloud/management/terragrunt.hclenter all the information underEnter manuallyblock. Remember to do the same for the other account their terragrunt files. -
Go to
cloud/management/00-organization/terragrunt.hcland fill in the local values underEnter manually, and under inputs fill in the primary, operational, securit, and billing contact information. Configure the accounts you would like to create. -
(Optional) If your IDP supports provisioning users and groups, you can skip this step, and delete the
cloud/management/02-iam-sso/01-usersfolder, and thecloud/management/02-iam-sso/02-groupsfolder.- Create the users list on
cloud/management/02-iam-sso/01-users/terragrunt.hcl, you can removejohn.doe@email.com. cloud/management/02-iam-sso/02-groups/terragrunt.hclenter the groups with the users you would like to create. Make sure to assign the users created by adding multipledependency.users.outputs.users["USER_EMAIL"].user_idand replaceUSER_EMAILwith the actual email.- On initial run align the
mock_outputvalue ofdependency "users"with01-users, make sure all emails registered01-usersarelisted.user_idvalue can be left"user_id"
- Create the users list on
-
(Optional) On
cloud/management/02-iam-sso/03-permission-sets/terragrunt.hclenter the permission-sets you would like to create. We have included some commonly used permission-sets. -
(Optional) On
cloud/management/02-iam-sso/04-account-assignment/terragrunt.hclassign accounts and permission-sets, to users and groups. The default value will deploy theAdministratorAccesspermission set for the Administrators group. -
Commit and push, it will trigger the pipeline to run.
- It will succesfuly create your AWS organization, and fail to create all other modules after that.
-
Then there are a few steps to be taken before re-runing the pipeline
- Open your AWS web console and navigate to Cloudformation => StackSets, then enable trusted access.
- Open your AWS web console and navigate to IAM Identity Center, then click on enable.
- You can now choose to use the AWS IAM Center Identity Directory, or configure your own Directory. Read the documentation here to proceed depending your Organization's IDP.
- If you choose to use the AWS IAM Identity Center Directory:
- Configure the MFA settings.
- On settings => Authentication, enable
Send email OTP for users created from API.
-
Re-run the failed pipeline and all IAM and StackSets should now deploy succesfully.
-
On
cloud/logs/terragrunt.hclenter all the information underEnter manuallyblock. Remember to do the same for the other account their terragrunt files. -
On
cloud/keys/terragrunt.hclenter all the information underEnter manuallyblock. Remember to do the same for the other account their terragrunt files. -
On
policies.hclreplaceYOUR_KEYS_ACCOUNT_IDwith the keys account ID. -
On
global.hclentermanagement_account_idandlogs_account_id. -
The pipeline jobs will fail because of missing dependencies, so you will have to retry them a few times until everything has been created.
-
Configure AWS profiles with AdminstratorAccess permissions on your local machine for all created AWS accounts.
-
Update
global.hclremote_state_bucketto the bucket created atcloud/management/04-terraform-state/01-bucket -
You can now migrate the Terraform state to the newly created Terraform state bucket, and delete the
terraform-stateCloudformation stack when finished. If you open a termimal in theclouddirectory, you can executeterragrunt --terragrunt-non-interactive run-all init -migrate-state -input=true, you will manually have to enter "yes" a number of times.
Error: enabling Security Hub Organization Admin Account (XXXXXXXXX): LimitExceededException: AWS Organizations can't complete your request because another request is already in progress. Try again later.
If you see this error, it means you are being rate limited by AWS. Simply re-run the failed pipeline and give it another shot.
-
Make Cloudformation bucket public with templates
-
Double check CI files and remove hardcodes
-
Add mock outputs to organization dependencies
We are Blackbird Cloud, Amsterdam based cloud consultancy, and cloud management service provider. We help companies build secure, cost efficient, and scale-able solutions.
Checkout our other 👉 terraform modules
Copyright © 2017-2023 Blackbird Cloud
