|
| 1 | +# Automated Cold Start Implementation |
| 2 | + |
| 3 | +The Baseline tier is commonly referred to as the Cold Start. |
| 4 | + |
| 5 | +## Quick Start |
| 6 | + |
| 7 | +The Cold Start is the most manually involved tier. Read through the following steps and see |
| 8 | +[the detailed documentation](https://docs.cloudposse.com/reference-architecture/setup/cold-start/manual-configuration) |
| 9 | +for edge cases. |
| 10 | + |
| 11 | +In short, |
| 12 | + |
| 13 | +| Steps | | |
| 14 | +| ------------------------- | ---------------------------------------------------- | |
| 15 | +| Install requirements | | |
| 16 | +| Build Geodesic | `make all` | |
| 17 | +| Vendor components | `atmos workflow vendor -f baseline` | |
| 18 | +| Configure root SuperAdmin | Click Ops | |
| 19 | +| Configure Terraform state | `atmos workflow init/tfstate -f baseline` | |
| 20 | +| Deploy AWS Organization | `atmos workflow deploy/organization -f accounts` | |
| 21 | +| Prepare accounts creation | Click Ops | |
| 22 | +| Deploy accounts | `atmos workflow deploy/accounts -f accounts` | |
| 23 | +| Deploy accounts settings | `atmos workflow deploy/account-settings -f accounts` | |
| 24 | +| Finalize account setup | Click Ops | |
| 25 | + |
| 26 | +## Prerequisites |
| 27 | + |
| 28 | +Follow the |
| 29 | +[prerequisites steps in the How-to Get Started guide](https://docs.cloudposse.com/reference-architecture/fundamentals/#prerequisites). |
| 30 | + |
| 31 | +Ensure Geodesic is fully up and running before continuing. |
| 32 | + |
| 33 | +### Before Running Terraform (ClickOps) |
| 34 | + |
| 35 | +First, you'll need to perform some ClickOps to ensure things are set up before we use Terraform to manage AWS accounts. |
| 36 | + |
| 37 | +From the root account: |
| 38 | + |
| 39 | +1. Enable |
| 40 | + [business support](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_support.html) in |
| 41 | + the `root` account (in order to expedite requests to raise the AWS member account limits) |
| 42 | +1. Set up the root IAM user account with a Virtual MFA device, following |
| 43 | + [the instructions in the AWS documentation](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_enable_virtual.html#enable-virt-mfa-for-root) |
| 44 | + for enabling a virtual MFA device for an AWS account root user. Save the MFA TOTP key in 1Password by using |
| 45 | + 1Password's TOTP field and built-in screen scanner to scan the QR code presented on the web page. |
| 46 | +1. [Create a `SuperAdmin` IAM User](https://docs.cloudposse.com/reference-architecture/setup/cold-start/how-to-create-superadmin-user/). |
| 47 | + Do not enable "console login", do set up MFA, and then create a single Access key. Create an API Credential for the |
| 48 | + `SuperAdmin` credentials in 1Password and store the Access Key ID, Secret Access Key, Assigned MFA device ARN, and |
| 49 | + TOTP key. This is the user we will use until AWS Team Roles (`aws-team-roles` component) are provisioned. |
| 50 | +1. For billing users, you need to enable IAM access. As the root user |
| 51 | + [open up the account settings for AWS Billing](https://us-east-1.console.aws.amazon.com/billing/home?region=us-east-1#/Account), |
| 52 | + then scroll to the section "IAM user and role access to Billing information" and enable it. |
| 53 | + |
| 54 | +For more details, see |
| 55 | +[the detailed documentation](https://docs.cloudposse.com/reference-architecture/setup/cold-start/#provision-account-settings-component). |
| 56 | + |
| 57 | +### (Optional) Enable Regions |
| 58 | + |
| 59 | +The 17 original AWS regions are enabled by default. If you are using a region that is not enabled by default (such as |
| 60 | +Middle East/Bahrain), you need to take extra steps. For details, see |
| 61 | +[the detailed documentation](https://docs.cloudposse.com/reference-architecture/setup/cold-start/#optional-enable-regions) |
| 62 | + |
| 63 | +## Initializing |
| 64 | + |
| 65 | +### The Toolbox Image |
| 66 | + |
| 67 | +Build the toolbox image locally before continuing. Follow the |
| 68 | +[toolbox image setup steps in the How-to Get Started guide](https://docs.cloudposse.com/reference-architecture/fundamentals/#building-the-toolbox-image). |
| 69 | +In short, run `make all`. |
| 70 | + |
| 71 | +The container will have the given local home mapped, so you should be able to use aws normally inside it once you set a |
| 72 | +profile that has valid credentials. For instance, if I log in to the profile `acme` with |
| 73 | +[leapp](https://github.com/Noovolari/leapp), I can run `aws --profile acme sts get-caller-identity` and get a response. |
| 74 | + |
| 75 | +Once you've verified that the infra container has access to aws resources, we can move on to the next step. |
| 76 | + |
| 77 | +### Setting up the Terraform State Backend |
| 78 | + |
| 79 | +This is where we configure and run Atmos. Atmos is a workflow automation tool that we will use to call Terraform which |
| 80 | +will provision all the accounts and resources you need to create and manage infrastructure. The Atmos configuration can |
| 81 | +be found in the `atmos.yaml`. |
| 82 | + |
| 83 | +If you're unfamiliar with atmos, you can read more about it [here](https://atmos.tools). |
| 84 | + |
| 85 | +If you look at `components/terraform/`, you'll see a bunch of directories. These contain Terraform "root modules" that |
| 86 | +are provisioned with Atmos. At first they'll only have their vendor files, such as |
| 87 | +`components/terraform/tfstate-backend/component.yaml`. |
| 88 | + |
| 89 | +You can use `atmos workflow vendor -f baseline` to vendor all the `baseline` modules, if the Terraform files are not |
| 90 | +present. You'll want to at least see Terraform files in `tfstate-backend` and `account-map`. |
| 91 | + |
| 92 | +Once you've done that, you can run `atmos workflow init/tfstate -f baseline` to deploy the Terraform Backend. |
| 93 | + |
| 94 | +Note that it can take a minute for the S3 buckets you created to become available. The workflow will attempt to wait |
| 95 | +until the bucket is created and available, with a 5-second delay between each check. Eventually, you should see this |
| 96 | +prompt: |
| 97 | + |
| 98 | +``` |
| 99 | +Initializing the backend... |
| 100 | +Do you want to migrate all workspaces to "s3"? |
| 101 | +``` |
| 102 | + |
| 103 | +Type `yes` to continue. This will migrate the state from the local backend to the s3 backend. |
| 104 | + |
| 105 | + |
| 106 | +:::info Granting SuperAdmin Access to TFState |
| 107 | + |
| 108 | +The IAM User for SuperAdmin will be granted access to Terraform State by principal ARN. This ARN is passed to the `tfstate-backend` stack catalog under `allowed_principal_arns`. Verify that this ARN is correct now. You may need to update the root account ID. |
| 109 | + |
| 110 | +::: |
| 111 | + |
| 112 | +## Deploying |
| 113 | + |
| 114 | +### Prepare Account Deployment |
| 115 | + |
| 116 | +Review the "account" configuration in the stack catalog. **This is the hardest part to change/fix once the accounts are |
| 117 | +provisioned**. If you aren't confident about the email configuration, account names, or anything else, now is the time |
| 118 | +to make changes or ask for help. |
| 119 | + |
| 120 | +You should double-check the following: |
| 121 | + |
| 122 | +1. `stacks/catalog/account.yaml` |
| 123 | +2. Run `atmos describe component account -s core-gbl-root` to inspect the final component configuration (e.g. _after_ |
| 124 | + all the mixins have been imported) |
| 125 | +3. Plan the run with `atmos terraform plan account -s core-gbl-root` |
| 126 | + |
| 127 | +Now deploy the AWS Organization. To deploy all accounts, we need to request an increase of the Account Quota from AWS |
| 128 | +support, which requires an AWS Organization to be created first. This process also enables |
| 129 | +[AWS RAM for Organizations](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_enable-ram.html) |
| 130 | +via a CLI command, which is required for connecting the Organization. |
| 131 | + |
| 132 | +Deploy the AWS Organization: |
| 133 | + |
| 134 | +```bash |
| 135 | +atmos workflow deploy/organization -f accounts |
| 136 | +``` |
| 137 | + |
| 138 | +### Requirements for Deploying Accounts |
| 139 | + |
| 140 | +Before performing the "Deploying Accounts" step, the root account needs to be configured as an AWS Organization. Once |
| 141 | +updated, complete the root account setup with the following ClickOps steps. |
| 142 | + |
| 143 | +From the `root` account (not `SuperAdmin`): |
| 144 | + |
| 145 | +1. Increase the |
| 146 | + [account quota to 20+](https://us-east-1.console.aws.amazon.com/servicequotas/home/services/organizations/quotas) for |
| 147 | + the Cloud Posse reference architecture, or more depending on your business use-case |
| 148 | + |
| 149 | +### Deploying Accounts |
| 150 | + |
| 151 | +:::info |
| 152 | + |
| 153 | +With the addition of support for dynamic Terraform roles, our `baseline` cold start refarch layer now depends |
| 154 | +on/requires that we have `aws-teams` and `aws-team-roles` stacks configured. This is because `account-map` uses those |
| 155 | +stacks to determine which IAM role to assume when performing Terraform in the account, and almost every other component |
| 156 | +uses `account-map` (indirectly) to chose the role to assume. |
| 157 | + |
| 158 | +::: |
| 159 | + |
| 160 | +Again verify the "account" configuration in `stacks/catalog/account.yaml`. |
| 161 | + |
| 162 | +Once confident, begin the accounts deployment: |
| 163 | + |
| 164 | +```bash |
| 165 | +atmos workflow deploy/accounts -f accounts |
| 166 | +``` |
| 167 | + |
| 168 | +These deployments will create all AWS member accounts and store relevant account metadata as "mappings" in the Terraform |
| 169 | +outputs of the `account-map` component. Rather than querying this `account` component each time we need an Account ID or |
| 170 | +role, we provision a static component `account-map`. **IMPORTANT:** Always run |
| 171 | +`atmos terraform apply account-map -s core-gbl-root` after provisioning accounts. |
| 172 | + |
| 173 | +Once you've created the accounts, you'll need to provision the baseline configuration within the accounts themselves. |
| 174 | +This is accomplished by running `atmos workflow deploy/account-settings -f accounts`. |
| 175 | + |
| 176 | +The workflows will kick off several sequential Terraform runs to provision all the AWS member account settings for |
| 177 | +member accounts in the Organization. |
| 178 | + |
| 179 | +#### ClickOps to Complete Account Setup |
| 180 | + |
| 181 | +For each new account: |
| 182 | + |
| 183 | +1. Perform a password reset by attempting to log in to the AWS console as a "root user", using that account's email |
| 184 | + address, and then clicking the "Forgot password?" link. You will receive a password reset link via email, which |
| 185 | + should be forwarded to the shared Slack channel for automated messages. Click the link and enter a new password. (Use |
| 186 | + 1Password or Random.org to create a password 26-38 characters long, including at least 3 of each class of character: |
| 187 | + lower case, uppercase, digit, and symbol. You may need to manually combine or add to the generated password to ensure |
| 188 | + 3 symbols and digits are present.) Save the email address and generated password as web login credentials in |
| 189 | + 1Password. While you are at it, save the account number in a separate field. |
| 190 | +1. Log in using the new password, choose "My Security Credentials" from the account dropdown menu and set up |
| 191 | + Multi-Factor Authentication (MFA) to use a Virtual MFA device. Save the MFA TOTP key in 1Password by using |
| 192 | + 1Password's TOTP field and built-in screen scanner. Also, save the Virtual MFA ARN (sometimes shown as "serial |
| 193 | + number"). |
| 194 | +1. While logged in, enable optional regions as described in the next step, if needed. |
| 195 | +1. (Optional, but highly recommended): Unsubscribe the account's email address from all marketing emails. |
| 196 | + |
| 197 | +For more details, review |
| 198 | +[the detailed "AWS Cold Start" documentation](https://docs.cloudposse.com/reference-architecture/setup/cold-start/#configure-root-account-credentials-for-each-account). |
| 199 | + |
| 200 | +Now that the accounts are bootstrapped, you can start setting up AWS Team Roles and Identities. |
| 201 | +[Continue to the Identity Setup](https://docs.cloudposse.com/reference-architecture/setup/identity/) |
| 202 | + |
| 203 | +# Related Topics |
| 204 | + |
| 205 | +## Mixins and Imports with Atmos |
| 206 | + |
| 207 | +As infrastructure grows, we end up with hundreds or thousands of settings for components and stack configurations. If we |
| 208 | +copy and paste these settings everywhere, it’s error-prone and not DRY. What we really want to do is to define a sane |
| 209 | +set of defaults and override those defaults when we need them to change. |
| 210 | + |
| 211 | +We accomplish this with Mixins. Mixins are imported into all stacks and each follow a set of rules. We use the |
| 212 | +`mixins/region` and `mixins/account` configurations to define common **variables** for all stacks. For example, |
| 213 | +`mixins/region/us-east-1.yaml` will define the variable `region: us-east-1`. |
| 214 | + |
| 215 | +**Note.** Do not import components into the account or region mixins. These are imported multiple times to define common |
| 216 | +variables, so any component imports would be duplicated and cause an Atmos error such as this: |
| 217 | + |
| 218 | +``` |
| 219 | +Executing command: |
| 220 | +/usr/bin/atmos terraform deploy account-settings -s core-gbl-artifacts |
| 221 | +
|
| 222 | +Found duplicate config for the component 'account-settings' for the stack 'core-gbl-artifacts' in the files: orgs/cch/core/artifacts/global-region/baseline, orgs/cch/core/artifacts/global-region/monitoring, orgs/cch/core/artifacts/global-region/identity. |
| 223 | +Check that all context variables in the stack name pattern '{tenant}-{environment}-{stage}' are correctly defined in the files and not duplicated. |
| 224 | +Check that all imports are valid. |
| 225 | +
|
| 226 | +exit status 1 |
| 227 | +``` |
0 commit comments