Create a remote statebucket

The cloudspin example code is implemented in Terraform, which uses state files to map the resources it manages to your project code.

Each stack instance you create will have its own statefile. There are various places you can store these statefiles, including your local hard drive, and hosted services. For our examples, we will store the state for our stack instances in S3. This preserves the state in the event that anything happens to your local files (e.g. accidentally deleting local statefiles). It also allows multiple people to work on the same stack instances from their own computers.

So a key part of bootstrapping is to create an S3 bucket that we can use to store the statefiles. We will use Terraform to create the S3 bucket, which creates a classic bootstrap situation - where do we store the state for the infrastructure that stores the state? The answer is that we will initially have the state for the S3 bucket on local disk, and then once the bucket is created, we will migrate the statefile into it.

Planning and creating your statebucket

The folder 00-statebucket has a cloudspin stack that will create a statebucket for you. This uses the s3bucket stack definition. Here’s how to do it.

(1) Create a local configuration file

Create a file 00-statebucket/stack-statebucket-local.yaml (you can copy 00-statebucket/stack-statebucket-local-example.yaml as a starter), and edit it:

instance:
  group: YOURNAME_sandbox

resources:
  aws_profile: YOUR_BOOTSTRAP_CREDENTIALS_PROFILE

YOUR_BOOTSTRAP_CREDENTIALS_PROFILE will be the name of the profile in ~/.aws/credentials with the bootstrap AWS API keys you created if you followed the steps in the previous page.

The group setting doesn’t matter too much. It’s essentially an ID for your environment, which, in more complex setups, can be used to integrate different things together. It is also used in tags.

(2) Initialize the local project tooling

In your 00-statebucket folder, run:

bundle install

This installs some Ruby gems that include the cloudspin tools we use in these examples. This is essentially a one-off, but when you want to update to newer versions of the tools, you’d run bundle update.

(3) Plan the bucket creation

Now you can see what changes Terraform will make:

rake plan

This downloads the cloudspin s3 bucket stack definition code, and then runs terraform plan.

(4) Create the bucket

rake up

Now you should have an S3 bucket that can be used for storing Terraform state. You’ll need the name of the bucket to put into configuration for further examples. The name should be something like: statebucket-cloudspin-examples-xxxxxxxxxxxx, where the number at the end is your AWS account ID (which is needed to make sure the bucket name is globally unique).

(5) Migrate your state to the bucket

Now you need to migrate your terraform state, which is currently in a local folder (./state/YOURNAME_sandbox), to the S3 bucket. This will allow other people in your team to make changes to the statebucket stack.

To migrate your state, you will need to edit your configuration to specify the S3 bucket as the location for the terraform_backend. When cloudspin runs and finds there is a local statefile, and also a remote backend configured, it will set things up so that terraform will migrate the state to the remote location.

So, edit your file 00-statebucket/stack-statebucket-local.yaml to add a terraform_backend section:

instance:
  group: YOURNAME_sandbox

resources:
  aws_profile: YOUR_BOOTSTRAP_CREDENTIALS_PROFILE

terraform_backend:
  bucket: YOURNAME_sandbox-XXXXXXXXXXXX
  profile: YOUR_BOOTSTRAP_CREDENTIALS_PROFILE
  region: eu-west-1
  encrypt: true

You can then run rake dry to see that there are no obvious errors. Unlike other actions, for migrating state from local to the remote bucket, the plan command will make it happen! This is because the "plan" command uses the state, so it carries out changes to backend, although it still won’t try to make changes to the infrastructure in the stack it actually manages.

When you do run:

rake plan

then you should expect to see the following in the output:

Initializing the backend...

Successfully configured the backend "s3"! Terraform will automatically
use this backend unless the backend configuration changes.

This shows that the bucket will be used for state. At the end, you should also see:

No changes. Infrastructure is up-to-date.

If instead you see that terraform will create all of the infrastructure elements, even though they already exist, then this usually means your state did not get migrated up to the s3 bucket.

(6) After IAM stack, switch to using the IAM roles

The next step of this tutorial is to create IAM roles that are used to run terraform more securely. Once those have been created, you can switch this stack to use those roles by editing your stack-instance-local.yaml file for this statebucket stack:

resources:
  aws_profile: YOUR_UNPRIVEGED_CREDENTIALS_PROFILE
  assume_role_profile: YOUR_ASSUME_DELIVERY_ROLE_PROFILE
  assume_role_arn: arn:aws:iam::XXXXXXXXXXXX:role/spin_role-cloudspin_examples-delivery

terraform_backend:
  bucket: YOURNAME_sandbox-XXXXXXXXXXXX
  profile: YOUR_UNPRIVEGED_CREDENTIALS_PROFILE
  role_arn: arn:aws:iam::XXXXXXXXXXXX:role/spin_role-cloudspin_examples-manager
  region: eu-west-1
  encrypt: true

Did you do all that?

If you’ve simply followed all of these instructions without having a close look at the code they apply to your cloud account, you have potentially put yourself at risk. This project code could easily have been created by someone unscrupulous. Even if you trust me and know this is my project, someone else could have compromised my project code, and inserted code to exploit your AWS account.

You should make it a habit to carefully vet code before you download and apply it.

In this case, the Ruby gems will have been downloaded into your local Ruby library folder, and the Terraform code will have been downloaded to ./00-statebucket/.cloudspin. I’d encourage you to review this code and make sure you’re comfortable with what it does before running it.

What next?

Now you can proceed to setting up IAM roles to use your AWS account a bit more securely.

results matching ""

    No results matching ""