This directory holds the reusable tooling for terraform-managed resources for the Jenkins Infrastructure Project.
-
The following tools (you may check the Docker image used by the CI at https://github.com/jenkins-infra/docker-hashicorp-tools with the up-to-date requirements):
-
The git command line to allow cloning the repository and its submodule shared-tools
-
From the root of your Terraform project, ensure that you have checked the submodule pointing to the current "shared-tools" repository (hosting this documentation) with the following command:
-
git submodule update --init --recursive
For each terraform project using this tooling, the following hypothesis are made:
-
There should be 2 different environments, each one with its own distinct set of cloud credentials (such as APi keys) and Terraform Backends:
-
"Staging" is used by the test harness and should be either empty or cleaned up regularly to avoid cloud costs
-
"Production" is where the real life and costs happen (as usual)
-
-
All tasks of the workflow (deployment, tests, etc.) should be done through a Jenkins Pipeline (read below) associated with the project repository (excepts for edge cases)
There is a Makefile, used either by the Jenkins Pipeline or an infrastructure administrator (e.g. manually) that provides the following commands:
-
make help
to print the Makefile manual with all available targets (useful when thisREADME
is not synced with theMakefile
) -
make lint
to statically lint the Terraform project resources. It fails if you didn’t. -
make prepare
to initialize the local Terraform project (⚠️ generates a temporary directory.terraform/
) -
make validate
to run a semantic and security validation of your Terraform project files -
make common-tests
to execute the "common" test harness on the project (uses the terratest code in./tests/
) -
make plan
to write the planned changes into $(PLAN_FILE_NAME) (but do NOT apply them) -
make deploy
to apply the changes to the infrastructure (implies terraform apply with no approval) -
make clean
to cleanup the local terraform setup (such as the.terraform/
directory)
Add the following Jenkins Pipeline Shared Library to your Jenkins instance: https://github.com/jenkins-infra/pipeline-library.
You can now use the function terraform()
in your Jenkins Pipeline to use the centralized workflow for Terraform.
It defines the following cases:
-
When a build starts on the principal branch:
-
If triggered by a code push (usually when a Pull Request is merged): no tests are run, but a terraform plan is executed followed by a deployment if it succeeds.
-
If triggered by a cron (usually daily), then both tests (see below) and terraform plan are executed, but no deployment are done. Please note that in this case, if the plan detects any change, then the build fails because a configuration drift happened.
-
If triggered manually then no tests are run at all, a terraform plan is executed on the production and a human must approve the pipeline for the deployment to production to happen
-
-
When a build starts on a Pull Request, then the tests are run AND a terraform plan is executed to give the maintainers an idea of what should happen if the Pull Request would be merged
The function terraform()
is defined in https://github.com/jenkins-infra/pipeline-library/blob/master/vars/terraform.groovy and can have the following arguments:
-
stagingCredentials
: (Optional - Default: "[]") list of Jenkins secrets to be used for the staging environment -
productionCredentials
: (Optional - Default: "[]") list of Jenkins secrets to be used for the production environment -
cronTriggerExpression
: (Optional - Default: "@daily") cron expression (as a string) to define when to trigger a build -
agentLabel
: (Optional - Default: "jnlp-linux-arm64"), Agent use, providing a reproductible environment (fixed versions of Terraform, trivy, golang, etc.) from the ALLINONE: https://github.com/jenkins-infra/packer-images -
runCommonTests
: (Optional - Default: true) Wether to execute the default (and common) test suite -
runTests
: (Optional - Default: false)Wether to execute custom tests provided by the current project by running the commandmake --directory=./tests/
from the root of the project.
Example Usage:
// Execute the terraform workflows in Jenkins
terraform(
stagingCredentials: [
string(variable: 'AWS_ACCESS_KEY_ID', credentialsId: 'ci-terraform-aws-access-key'),
string(variable: 'AWS_SECRET_ACCESS_KEY', credentialsId:'ci-terraform-aws-secret-key'),
file(variable: 'BACKEND_CONFIG_FILE', credentialsId: 'ci-terraform-aws-backend-config'),
],
productionCredentials: [
string(variable: 'AWS_ACCESS_KEY_ID', credentialsId: 'production-terraform-aws-access-key'),
string(variable: 'AWS_SECRET_ACCESS_KEY', credentialsId:'production-terraform-aws-secret-key'),
file(variable: 'BACKEND_CONFIG_FILE', credentialsId: 'production-terraform-aws-backend-config'),
],
)