This orb can be used to plan and apply terraform modules.
It is published as ovotech/terraform-v2@2
.
Note: this orb only supports terraform >=0.14
.
If you're upgrading from terraform orb v1, see the upgrade guide.
The orb provides executors for running terraform commands. An executor defines the docker image to use for jobs.
It contains:
- tfmask
- tfswitch
- google-cloud-sdk
- aws-cli
- Helm 3+ available as
helm
andhelm3
See Using Helm 3 - stable "ovo" provider with ovo_kafka_user resource (
source = "terraform.ovotech.org.uk/pe/ovo"
) - stable "aiven-kafka-users" provider with aiven-kafka-users_user resource that enables auto-rotation of credentials (
source = "terraform.ovotech.org.uk/pe/aiven-kafka-users"
)
Terraform can obtain credentials from environment variables set in circleci.
For the AWS provider, set the AWS_ACCESS_KEY and AWS_SECRET_ACCESS_KEY environment variables.
For the gcloud provider, set GCLOUD_SERVICE_KEY to be a GCP service account key as a base64 encoded or plain text string. You may optionally set GOOGLE_PROJECT_ID to the ID of the project running the cluster. If you have provided the project ID then you may set GOOGLE_COMPUTE_ZONE too — you cannot set zone on its own.
If GITHUB_USERNAME and GITHUB_TOKEN environment variables are set,
the plan
command will add a comment on an open PR with the plan.
By default, when using the apply
command the plan must have been approved
by being merged from a PR that has had a comment added by a previous plan
command.
If the plan is not found or has drifted, then the apply
command will fail.
This is to ensure that the orb only applies changes that have been reviewed by a human.
You can disable this behaviour by setting auto_approve: true
in the apply
step,
which will always apply any terraform changes.
See the orb doc for a list of available commands.
See the orb docs for a list of available jobs.
These jobs run their respective command in the default executor. The jobs have the same parameters as the commands.
In this example a plan for the module in tf/ is generated and attached to the open PR. If that PR is then merged, the plan is applied.
version: 2.1
orbs:
terraform: ovotech/terraform-v2@2
workflows:
test:
jobs:
- terraform/plan:
path: tf
filters:
branches:
ignore: master
- terraform/apply:
path: tf
filters:
branches:
only: master
This configuration defines it's own plan and apply jobs which use the orb's plan and apply commands on multiple terraform modules.
It also configures a helm repo within the the container for use with the terraform helm provider.
version: 2.1
orbs:
terraform: ovotech/terraform-v2@2
jobs:
terraform_plan:
executor: terraform/default
steps:
- checkout
- run:
name: Add helm repo
command: |
echo $GOOGLE_SERVICE_ACCOUNT | base64 -d > /tmp/google_creds
export GOOGLE_APPLICATION_CREDENTIALS=/tmp/google_creds
gcloud auth activate-service-account --key-file=/tmp/google_creds
helm plugin install https://github.com/nouney/helm-gcs --version 0.1.4
helm repo add helm-example gs://<my_google_bucket>/
- terraform/plan:
path: terraform/deployments/cluster
workspace: helm-example-uat
- terraform/plan:
path: terraform/deployments/cluster-init
workspace: helm-example-uat
- terraform/plan:
path: terraform/deployments/helm-example-uat
- terraform/plan:
path: terraform/deployments/cluster
workspace: helm-example-prd
- terraform/plan:
path: terraform/deployments/cluster-init
workspace: helm-example-prd
- terraform/plan:
path: terraform/deployments/helm-example-prd
- terraform/plan:
path: terraform/deployments/sqs-test
terraform_apply:
executor: terraform/default
steps:
- checkout
- run:
name: Add helm repo
command: |
echo $GOOGLE_SERVICE_ACCOUNT | base64 -d > /tmp/google_creds
export GOOGLE_APPLICATION_CREDENTIALS=/tmp/google_creds
gcloud auth activate-service-account --key-file=/tmp/google_creds
helm plugin install https://github.com/nouney/helm-gcs --version 0.1.4
helm repo add helm-example gs://<my_google_bucket>/
- terraform/apply:
path: terraform/deployments/cluster
workspace: helm-example-uat
- terraform/apply:
path: terraform/deployments/cluster-init
workspace: helm-example-uat
- terraform/apply:
path: terraform/deployments/helm-example-uat
- terraform/apply:
path: terraform/deployments/cluster
workspace: helm-example-prd
- terraform/apply:
path: terraform/deployments/cluster-init
workspace: helm-example-prd
- terraform/apply:
path: terraform/deployments/helm-example-prd
- terraform/apply:
path: terraform/deployments/sqs-test
workflows:
commit:
jobs:
- terraform_plan:
filters:
branches:
ignore: master
- terraform_apply:
filters:
branches:
only: master
If you are using Helm 3 (terraform provider > v1) you must explicitly add
repositories, this includes charts in stable
which is no longer included
in Helm by default.
This can be done using the helm3
command prior to any apply jobs.
terraform_apply:
executor: terraform/default
steps:
- checkout
- run:
name: Add helm repo
command: |
helm3 repo add stable https://kubernetes-charts.storage.googleapis.com
helm3 repo update
- terraform/apply:
path: terraform/deployments/cluster
workspace: helm-example-uat
The helm
command will use helm3
by default.
version: 2.1
orbs:
terraform: ovotech/terraform-v2@2
jobs:
terraform_plan:
executor: terraform/default
environment:
AIVEN_PROVIDER: true
steps:
- checkout
- terraform/plan:
path: tf
workflows:
test:
jobs:
- terraform_plan:
filters:
branches:
ignore: master
This examples checks the infrastructure every morning. If changes are detected to any of the terraform resources the build is failed.
version: 2.1
orbs:
terraform: ovotech/terraform-v2@2
workflows:
nightly:
triggers:
- schedule:
cron: "0 8 * * *"
filters:
branches:
only:
- master
jobs:
- terraform/check:
path: prod
To attach the plan to a PR, create the GITHUB_USERNAME and GITHUB_TOKEN
environment variables in the CircleCI project. This should be the username
(not email address) and a Personal Access Token of a github user that has access to
the repo. The token requires the repo, write:discussion
scopes.
It's recommended to enable "Only build pull requests" in your CircleCI
config when using this setting. If not enabled this could lead to a creation
of a PR after the CircleCI job has run, which means the Plan comment cannot be
added. Settings can be found under "Advanced Settings" e.g. https://circleci.com/gh/ovotech/$YOUR_REPO/edit#advanced-settings
To make best use of this orb, require that the plan is always reviewed before merging the PR to approve. You can enforce this in github by going to the branch settings for the repo and enable protection for the master branch:
- Enable 'Require pull request reviews before merging'
- Check 'Dismiss stale pull request approvals when new commits are pushed'
- Enable 'Require status checks to pass before merging'
- Select the 'ci/circleci: terraform_plan' check.
- Enable 'Require branches to be up to date before merging'
- In the CircleCI project advanced settings, enable 'Only build pull requests'.
You can use this orb with private Terraform Module registries.
To specify the registry api token, set TF_REGISTRY_HOST and TF_REGISTRY_TOKEN environment variables in the CircleCI settings.
The terraform commands use tfmask to mask sensitive output for these resources:
- random_id
- kubernetes_secret
- acme_certificate
You can customise this list using the TFMASK_RESOURCES_REGEX environment variable. See the tfmask docs for details. Please create a github issue to suggest additional resources that need masking.
The version of terraform to use is discovered from the first of:
- A
required_version
constraint in the terraform configuration. - A tfswitch
.tfswitchrc
file - A tfenv
.terraform-version
file in path of the terraform configuration.
The required_version
constraint goes somewhere in your terraform configuration:
terraform {
required_version = "0.15.0"
}
tfswitch and tfenv make it easy to install the correct version locally.
Their config files contain a terraform version number to use:
0.15.0