Skip to content

Latest commit

 

History

History
198 lines (130 loc) · 8.48 KB

File metadata and controls

198 lines (130 loc) · 8.48 KB

2. Configure continuous deployment with Travis

Now that we have defined our Fastly service using Terraform locally; we want to be able to reliably reproduce the infrastructure configuration in a continuous integration environment and deploy our changes to the service every time we check our config into version control such as GitHub. To achieve this we are going to use the open-source tool Travis CI.

Travis CI provides a hosted build environment and default set of steps to test, build and deploy project artefacts. You can customize any step in this process in a .travis.yml yaml file in the root of your repository. Travis uses the file to learn about your project and how you want your builds to be executed.

2.1 Setup Travis

  1. Sign in to Travis CI with your GitHub account, accepting the GitHub access permissions confirmation.

  2. Once you’re signed in, Travis will synchronize your repositories from GitHub, go to your profile page and enable Travis CI for your workshop repository github.com/<USERNAME>/altitude-ci-cd-workshop by toggling the associated switch.

Travis repo toggle

Note: you may need to get Travis to sync with GitHub again.

Travis sync

2.2 travis.yml configuration

Once Travis is configured and authorised for your repository we can add a .travis.yml file. This declares the actions we'd like Travis perform in the CI environment whenever we change our configuration.

Edit the file named .travis.yml within the root directory of our project using your text editor of choice.

A build on Travis CI is made up of three steps, all of which can be customized using the the yaml declaration format inside our .travis.yml file:

  1. install: install any dependencies required
  2. script: run the build script
  3. deploy: deploy the artefacts

Note: There are actually more than 3 steps including some optional ones. The complete build lifecycle and hooks and information on how to customize them further can be found on the within the Travis docs.

The before_install step tells Travis to install the Terraform binary and place on the $PATH so it is avaliable to use within our build environment. The script and deploy steps should be familiar, it's the terraform plan commands that we ran in the first exercise.

2.3 Push to Travis

Make an empty commit and push to travis.

$ git commit --allow-empty -m "Force travis run"
$ git push origin master

Navigate back to the Travis CI dashboard. After a few moments, you should see a build start and eventually fail. You should have an error like this:

Errors:
  * 2 error(s) occurred:
  * Required variable not set: fastly_name
  * Required variable not set: fastly_api_token

Locally, we were using terraform.tfvars to store our sensitive variables. That is not checked into git, so Travis CI does not have access to those values. We need to provide those to Travis, securely.

2.4 Encrypt Fastly API token and service

For obvious security reasons its a very bad idea to store any sensitive data such as our Fastly API token in plain-text within our source code. Especially on an open-source project like this. Fortunately, Travis provides a way to encrypt and store secrets in the yaml file using public/private key signing.

Terraform reads any variables from the environment prefixed with TF_VAR_<variable name>, such as TF_VAR_fastly_api_token. We can leverage this feature on Travis, since Travis supports securely storing environment variables.

You can find your API key and service name in terraform.tfvars.

Using the Travis binary (installed during setup) run the following command to add your token and service id to the Travis file:

$ travis encrypt TF_VAR_fastly_api_token=<YOUR_TOKEN> --add

Run the same command to generate the value for your service id:

$ travis encrypt TF_VAR_fastly_name=<YOUR_NAME> --add

Your .travis.yml file should now have an env declaration at the bottom of the file and should look something like this:

env:
  global:
    secure:
      # ...

Note: Travis parses the YAML file, so our comments actually get removed :(.

2.4 Add, commit, push, and build

To get Travis to trigger our newly defined build with environment variables within CI, we need to add the changed files in our working directory and push them to GitHub. Travis will observe the change to our repository and automatically start a build to run our install and script commands defined in the .travis.yml in the CI environment.

$ git add -A
$ git commit -m 'Testing Travis CI'
$ git push origin master

Wait for Travis CI to run a build on your fork of the altitude-ci-cd-workshop repository. You can view the output and build status by navigating to: https://travis-ci.org/<USERNAME>/altitude-ci-cd-workshop. Click on the branches tab if the build has not started yet. Depending on the time of day this may take some time.

You should have see the output of our terraform plan in the job log tab:

Travis plan build log

2.5 Continuously deploy:

Now that we have Travis continuously integrating our changes whenever we push changes to our terraform configuration to GitHub, we can use the deploy: step inside .travis.yml to actually apply our changes to our Fastly service in production.

Review the following declaration the bottom of your .travis.yml file:

deploy:
- provider: script
  skip_cleanup: true
  script: terraform apply ./terraform
  on:
    branch: master

The script: declaration inside the deploy block is the command that Travis will execute when running the deploy step. Here we have simply ran our terraform apply command as per the last exercise:

  script: terraform apply ./terraform

As we only want to deploy the changes to our service once we are satisfied with them (such as tests passing in the script step, peer reviewed by a colleague etc.) via a pull request into the master branch. We can tell Travis to only deploy the changes on a merge into the master branch via the on: declaration of the deploy block. I.e. only perform "this" action on "this" branch.

  on:
    branch: master

2.5 Make a change

In order to test our pipeline, we need to make a change.

First, create a new branch. In a real production scenario, you would likely seek peer review using a Pull Request workflow, so let's mirror that here.

$ git checkout -b changes

Next, let's add a second domain to our main.tf. After the first domain stanza, add a second domain stanza which a "-2" suffix.

# terraform/main.tf

resource "fastly_service_v1" "my-fastly-service" {
  name = "${var.fastly_name}"

  # ...

  domain {
    name = "${var.fastly_name}-2.fastly-altitude-2017.com" # <--
  }

  # ...

Add and commit these changes:

$ git add -A
$ git commit -m 'Testing Travis CI deployment'
$ git push origin changes

Raise a new pull request for the branch changes in GitHub and merge it:

  1. Navigate to the repository on GitHub and click "Compare & pull request"

Compare & pull request

  1. Fill out the PR form title and description. Note: ensure we are merging into the base master of our forked repo and not the upstream master

PR form

  1. Click the "Merge pull request" button

Merge pull request

If you jump back over to travis-ci.org you should now be able to watch the build of the master branch with our newly added deployment step creating our Fastly service.

You should see the apply output in the build log.

Travis apply success

2.6 Celebrate! 🎉

If your configuration was successfully applied via Travis CI you should be able to curl your newly updated service on it's secondary domain.

$ curl -v http://<YOUR SERVICE DOMAIN>.global.prod.fastly.net/index.html

HTTP/1.1 200 OK
Cache-Control: public, max-age=3600
Content-Type: text/html
Content-Length: 11651
Connection: keep-alive
X-Served-By: cache-lcy1136-LCY
X-Cache: HIT
X-Cache-Hits: 1

If you don't believe this you can even login to the Fastly web interface and look at your configuration.