/tiller

Deploy Trellis, Bedrock and Sage via AWS CodeBuild

Primary LanguageDockerfile

[Deprecated] Use ItinerisLtd/tiller-circleci-orb instead.


Tiller

Deploy Trellis, Bedrock and Sage via AWS CodeBuild.

Requirements

What's in the box?

Set Up

You need a robot user for deployment. In this example, we will use a GitHub machine user account as our robot. For simplicity, this robot uses the same SSH key pair to access both GitHub private repos and the web server.

GitHub

  1. Sign up a machine user on GitHub
  2. Grant mybot read access to all necessary private repos
  3. Generate a SSH key pair
    • ssh-keygen -t ed25519 -C "mybot-$(date)"
    • It must use a passphrase
  4. Upload the public key to Github

Trellis

  1. Add the SSH key to web server
    # group_vars/<env>/users.yml
    users:
      - name: "{{ web_user }}"
        groups:
          - "{{ web_group }}"
        keys:
          - https://github.com/human.keys
          - https://github.com/mybot.keys # <-- This line
      - name: "{{ admin_user }}"
        groups:
          - sudo
        keys:
          - https://github.com/human.keys
  2. Re-provision ansible-playbook server.yml -e env=<env> --tags users

buildspec.yml

Tiller comes with 2 different buildspec.yml examples. They are expecting different Trellis and Bedrock structures.

Use buildspec.yml if your directory structure follow the official documents:

example.com/      # → Root folder for the project
├── .git/         # → Only one git repo
├── trellis/      # → Your clone of roots/trellis, directory name must be `trellis`
└── site/         # → A Bedrock-based WordPress site, directory name doesn't matter

buildspec.itineris.yml do extra steps for itineris-specific project setup.

At Itineris, we use a opinionated project structure:

  • separate Trellis and Bedrock as 2 different git repo
  • name the Bedrock-based WordPress site directory more creatively, i.e: bedrock
  • extra deploy command parameter for our SSH bastion host, i.e: -e bastion_user=$BASTION_USER
example.com/      # → Root folder for the project
├── bedrock/      # → A Bedrock-based WordPress site, directory name must be `bedrock`
│   └── .git/     # Bedrock git repo
└── trellis/      # → Clone of roots/trellis, directory name must be `trellis`
    └── .git/     # Trellis git repo

See: roots/trellis#883 (comment)

To install:

  • Option A: Use the buildspec.yml in the source code root directory

    1. Copy and commit the .yml file to project root
    2. Review the .yml file, change if necessary
    3. Enter the .yml file name on AWS web console
  • Option B: Insert build commands via AWS web console

    1. Copy and paste the .yml file to AWS web console
    2. Review the commands, change if needed

AWS CodeBuild

Docker Image

Use itinerisltd/tiller. See below.

Environment Variables

Name Value Type
PRIVATE_KEY /ssm/the-private-key Parameter Store
PRIVATE_KEY_PASSPHRASE /ssm/the-passphrase Parameter Store
SITE_ENV production Plaintext
SITE_KEY example.com Plaintext
BASTION_USER mybot Plaintext buildspec.itineris.yml only, omit BASTION_USER for Kinsta
TRELLIS_REPO git@github.com:xxx/yyy.git Plaintext buildspec.itineris.yml only
PRIVATE_KEY & PRIVATE_KEY_PASSPHRASE

Encrypt PRIVATE_KEY and PRIVATE_KEY_PASSPHRASE with AWS Systems Manager Parameter Store and AWS KMS. Never save them in plaintext!

PRIVATE_KEY needs line break characters(\n) For example:

➜ cat ~/.ssh/mybot
-----BEGIN OPENSSH PRIVATE KEY-----
aaa
bbb
ccc
-----END OPENSSH PRIVATE KEY-----

Then, save PRIVATE_KEY as:

-----BEGIN OPENSSH PRIVATE KEY-----\naaa\nbbb\nccc\n-----END OPENSSH PRIVATE KEY-----

SITE_ENV & SITE_KEY

They are used to build the final deploy command:

# ansible-playbook deploy.yml -e env=$SITE_ENV -e site=$SITE_KEY -vvvv
➜ ansible-playbook deploy.yml -e env=production -e site=example.com -vvvv

Examples

Docker Image

Tiller comes with a docker image to run Trellis deployment:

This is sufficient for deploying a default Trellis, Bedrock and Sage project. You can build your own docker image if necessary:

# Modify `Dockerfile`

# Build the image without caches
# Not using caches because we want latest packages to be installed
➜ docker build --no-cache --compress --tag tiller .

# Tag the image
➜ docker tag tiller itinerisltd/tiller:2018.5.18.2
➜ docker tag tiller itinerisltd/tiller:latest

# Push the image
➜ docker push itinerisltd/tiller:2018.5.18.2
➜ docker push itinerisltd/tiller:latest

FAQ

Is it a must to use all Trellis, Bedrock and Sage?

No, you don't need all of them. Only Trellis is required.

Is it a must to use AWS CodeBuild?

No. You can use the docker image without AWS CodeBuild.

Is it a must to use GitHub?

No.

Can I use multiple SSH key pairs?

Yes.

phases:
  pre_build:
    commands:
      - echo "$PRIVATE_KEY" > $HOME/.ssh/id_rsa
      - echo "$PRIVATE_KEY_SECOND" > $HOME/.ssh/id_rsa_second
      - chmod 600 $HOME/.ssh/id_rsa*
      - expect-ssh-add.sh id_rsa $PRIVATE_KEY_PASSPHRASE
      - expect-ssh-add.sh id_rsa_second $PRIVATE_KEY_PASSPHRASE_SECOND

What does S3 bucket cache?

By default only yarn packages are cached. It speeds up the build by 20~60 seconds. This is optional and you can add more cache.paths.

Author Information

Tiller is a Itineris Limited project created by Tang Rufus.

Special thanks to the Roots team whose Trellis make this project possible.

Full list of contributors can be found here.

Feedback

Please provide feedback! We want to make this library useful in as many projects as possible. Please submit an issue and point out what you do and don't like, or fork the project and make suggestions. No issue is too small.