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
GitHubIdentityProviderArn
with the ARN of the IDP created on thegithub-oidc-provider
stack. Fill inSubjectClaimFilters
with the following data relating to your infra reporepo:YOUR_GITHUB_ORGANIZATION/YOUR_GITHUB_REPOSITORY_NAME:ref:refs/heads/BRANCH_NAME
we advise to deploy usemain
as 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. ForGitHubActionsJumpRoleName
use the same name as you will on theiam-role
stackRoleName
parameter. - For the
terraform-state
stack, fill inGithubActionsRoleArn
with the role ARN created in thegithub-oidc-role
stack. 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-role
stack, fill inPrincipalARN
with the role ARN created in thegithub-oidc-role
stack. Make sure to write down the Role name, and configure it inglobals.hcl
atgithub_role_name
. UnderManagedPolicyARNs
one 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 ARN
created by github-oidc-role stackAWS_REGION
: fill in your selected AWS region.
-
On
.github/workflows/aws_deployment.yml
update all occurences of<my-project-name>
to your github repository name, line 46. -
On
global.hcl
enter all the required information at theEnter manually
block. -
On
cloud/management/terragrunt.hcl
enter all the information underEnter manually
block. Remember to do the same for the other account their terragrunt files. -
Go to
cloud/management/00-organization/terragrunt.hcl
and 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-users
folder, and thecloud/management/02-iam-sso/02-groups
folder.- 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.hcl
enter 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_id
and replaceUSER_EMAIL
with the actual email.- On initial run align the
mock_output
value ofdependency "users"
with01-users
, make sure all emails registered01-users
arelisted
.user_id
value can be left"user_id"
- Create the users list on
-
(Optional) On
cloud/management/02-iam-sso/03-permission-sets/terragrunt.hcl
enter 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.hcl
assign accounts and permission-sets, to users and groups. The default value will deploy theAdministratorAccess
permission 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.hcl
enter all the information underEnter manually
block. Remember to do the same for the other account their terragrunt files. -
On
cloud/keys/terragrunt.hcl
enter all the information underEnter manually
block. Remember to do the same for the other account their terragrunt files. -
On
policies.hcl
replaceYOUR_KEYS_ACCOUNT_ID
with the keys account ID. -
On
global.hcl
entermanagement_account_id
andlogs_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.hcl
remote_state_bucket
to 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-state
Cloudformation stack when finished. If you open a termimal in thecloud
directory, 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