Skip to content

Instantly share code, notes, and snippets.

@joe-niland
Last active November 7, 2020 23:59
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save joe-niland/b96150bfc13828c2a58751dfca7ffe7e to your computer and use it in GitHub Desktop.
Save joe-niland/b96150bfc13828c2a58751dfca7ffe7e to your computer and use it in GitHub Desktop.

Notes on using Geodesic with repos created by cloudposse/reference-architectures

How to Use this Repo

AWS Setup

  1. Log in to console for root account as your IAM user name@example.com
  2. Go to https://console.aws.amazon.com/iam/home
  3. Add an MFA device to your user
  4. Generate an access key and store it securely to be added to aws-vault

Changes made from repo generated by the cold start process

Dockerfile

  1. Change: FROM cloudposse/geodesic:0.123.1
  2. Change: RUN apk add --update terraform_0.11@cloudposse terraform_0.12@cloudposse

..net/conf/tfstate-backend/terraform.envrc

(Change version to 0.90.0)

export TF_CLI_INIT_FROM_MODULE="git::https://github.com/cloudposse/terraform-root-modules.git//aws/tfstate-backend?ref=tags/0.90.0"

First time only

git clone <stage>.example.com
cd <stage>.example.com

Create Overrides and Preferences files as needed

mkdir ~/.geodesic/overrides.d ~/.geodesic/preferences.d

If you want to change where the Geodesic config files are stored, set GEODESIC_CONFIG_HOME in your profile.

Example: override SSH key path

If your private key is not located at ~/.ssh/id_rsa, edit Dockerfile, and add:

echo "export SSH_KEY=/localhost/.ssh/id_rsa_my_key" > ~/.geodesic/overrides.d/ssh
Example: override AWS_DEFAULT_PROFILE

If your AWS profile is not named in the standard way you could change the env var.

echo "export AWS_DEFAULT_PROFILE=\${NAMESPACE}-\${STAGE}-admin" > ~/.geodesic/overrides.d/aws

Build Docker image and add invoke script

make init
make docker/build
make install

Usage

The following command will start a shell session within the Docker image for the stage.

<stage>.example.com

You will need to enter your private ssh key's passphrase if it has one.

The first time you load the shell you should configure your AWS credentials

aws-config-setup

Follow the prompts. On the first time you do this, you'll need to enter the access key you created above. Make sure you say 'y' to Use MFA?. This script will add your credentials to your local aws-vault storage. You need to do this for each repo/account but the second time you do it you can skip adding the credentials since they have already been added. Here is example output:

First time:

⧉  dev 
 ✗ . (none) ~ ⨠ aws-config-setup 
Use MFA? [y/n] y
AWS IAM Username: me@example.com
Setup AWS Credentials (aws-vault)? [y/n] y
Enter Access Key ID: AK.......
Enter Secret Access Key: 2dc.....
Enter passphrase to unlock /conf/.awsvault/keys/: 
Added credentials to profile "example" in vault
Configured AWS example-dev-admin profile for ap-southeast-2 region in the xxx548454819 account
-> Run 'assume-role' to login to AWS with aws-vault
 ⧉  dev 
 ✗ . (none) ~

Second (and subsequent times):

 ⧉  root.example.com
 ✗ . (none) ~ ⨠ aws-config-setup 
Use MFA? [y/n] y
AWS IAM Username: me@example.com
Setup AWS Credentials (aws-vault)? [y/n] n
Configured AWS example-root-admin profile for ap-southeast-2 region in the xxx392324150 account
-> Run 'assume-role' to login to AWS with aws-vault
 ⧉  root.example.com
 ✗ . (none) ~

Log in to AWS:

assume-role

You should see something like:

. (none) ~ ⨠ assume-role
* Docker clock is 2 seconds behind Host clock
Enter passphrase to unlock /conf/.awsvault/keys/: 
Enter token for arn:aws:iam::xxx392324150:mfa/me@example.com: 123456
* Assumed role arn:aws:iam::xxx548454819:role/OrganizationAccountAccessRole
* Found SSH agent config
 ⧉  dev 
 √ : (example-dev-admin) ~

If you change something in conf/ you must re-run make docker/build

Developing per-account Terraform modules

To avoid rebuilding the Docker image every time you change something in the repo, from within the Geodesic container cd to your repo conf directory inside your mounted local drive.

From this directory you can use Geodesic's tools to work with Terraform modules.

For example:

cd /localhost/projects/example/dev.example.com/conf/my-module
make

Once you have everything working you should commit the changes and rebuild the Geodesic image for the account.

Changes for Terraform 0.12

If you want to develop a module that requires Terraform 0.12, you must make the following changes:

Makefile.tasks

(replace with:)

$(shell mkdir -p ${TF_MODULE_CACHE})
-include ${TF_MODULE_CACHE}/Makefile

## Fetch the remote terraform module
deps:
	terraform init

## Reset this project
reset:
	rm -rf Makefile *.tf .terraform ${TF_MODULE_CACHE}

.envrc

(change 0.11 to 0.12)

use envrc
use terraform 0.12
use atlantis
use tfenv

terraform.envrc

Add:

export TF_MODULE_CACHE=.module

Testing and applying the module

make
terraform plan
terraform apply

If you change the root module, run make reset && make to refresh the module from git.

If Terraform seems to hang, re-run the command prefixed with TF_LOG=DEBUG. Usually it's caused by an expired session token.

Notes on using cloudposse/reference-architectures

Account Provisioning

This is done in multiple steps:

  1. Use Cloud Posse's reference architecture to:
    1. provision AWS account structure with:
      1. Terraform requirements
      2. fundamental services (e.g. CloudTrail)
      3. initial admin users
    2. build repos for each AWS account
  2. Push each repo to your own git server, then augment with modules specific to each account

Assumptions

  1. Root account created in AWS and email verified
  2. Completed support request to AWS to have account per Organization limit raised
  3. Terraform 0.11 installed and in path. You might want to install tfswitch so you can easily switch between 0.11 and 0.12.

Creation of Account Repos

These instructions are expanded from https://github.com/cloudposse/reference-architectures#get-started

  1. Log in to root account console using your root account's root user
    1. Create new IAM group admin
    2. Assign AdministratorAccess policy to the group
    3. Create an IAM user with the name admin or root or whatever
    4. Add the user to the admin group
    5. Enable MFA for the user and record MFA ARN
    6. Generate Access Key ID and Secret Access Key for the user
  2. Set up aws-vault on your computer - see prereqs
  3. Install Docker and Terraform 0.11 - see prereqs
  4. Clone https://github.com/cloudposse/reference-architectures.git
  5. Edit configs/root.tfvars and set:
    1. domain

    2. namespace

    3. aws_region

    4. account_email

    5. Required accounts in accounts_enabled - delete the ones you don't need

      Make sure you use the account names found at https://github.com/cloudposse/reference-architectures#architecture. Using other names will generate errors when provisioning. Think carefully about which accounts you need. If you try to change this list later (after running make root) Terraform will try to destroy the accounts which won't work until you've gone through the account setup process.

    6. users

    7. Any other variables you need to change. The above are probably the most common.

  6. Create root repo and provision account
    cd reference-architectures
    export AWS_SECRET_ACCESS_KEY=...secret from above...
    export AWS_ACCESS_KEY_ID=...key from above...
    make root
    This will download the geodesic Docker image, used for running Terraform and other tools.

If you encounter errors, first try running make root/init-resume or just make root - it could be a race condition or the hitting of an AWS service limit. If you continue to get errors ask in #geodesic

A specific error you may hit is:
  ```
  Error: Target directory does not exist

  Cannot initialize non-existent directory accounts/root.

  make: *** [root/init] Error 1
  ```
This is related to using Terraform 0.12. Try again with 0.11.
  1. Once make root is finished, run make children. As above, you may need to re-run this if you get errors.
  2. Once make children is finished, run make finalize.
  3. Now push the created repos to your Git account. For each :
    cd repos/<stage>.example.com
    git init
    git remote add origin ...
    git add .
    git commit -m "initial commit"
    git push -u origin
  4. Log in to AWS console using the root account's root user and delete the admin account, or at least delete the access keys which were used to run the above process.

Since these processes use Terraform, which is generally idempotent, you can run the above commands as many times as you like without any problems. You may need to do this to make various changes, add new users, etc, while you are still setting up the accounts. The reference-architecture repo is not designed to be used after the accounts have begun to be used.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment