Commit 9bf0d766 authored by Matt Kasa's avatar Matt Kasa Committed by Amy Qualls

Update infrastructure docs for Terraform

- Makes references to variables consistent
- Uses `terraform-images` pre-built image
- Uses `gitlab-terraform` helper

Relates to https://gitlab.com/gitlab-org/gitlab/-/issues/216785
Relates to https://gitlab.com/gitlab-org/gitlab/-/issues/216854
parent 4ffc25de
...@@ -8,6 +8,8 @@ info: To determine the technical writer assigned to the Stage/Group associated w ...@@ -8,6 +8,8 @@ info: To determine the technical writer assigned to the Stage/Group associated w
## GitLab managed Terraform State ## GitLab managed Terraform State
> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/2673) in GitLab 13.0.
[Terraform remote backends](https://www.terraform.io/docs/backends/index.html) [Terraform remote backends](https://www.terraform.io/docs/backends/index.html)
enable you to store the state file in a remote, shared store. GitLab uses the enable you to store the state file in a remote, shared store. GitLab uses the
[Terraform HTTP backend](https://www.terraform.io/docs/backends/types/http.html) [Terraform HTTP backend](https://www.terraform.io/docs/backends/types/http.html)
...@@ -95,64 +97,73 @@ to the repository. ...@@ -95,64 +97,73 @@ to the repository.
} }
``` ```
1. In the root directory of your project repository, configure a `.gitlab-ci.yaml` file. 1. In the root directory of your project repository, configure a
This example uses a pre-built image: `.gitlab-ci.yaml` file. This example uses a pre-built image which includes a
`gitlab-terraform` helper. For supported Terraform versions, see the [GitLab
Terraform Images project](https://gitlab.com/gitlab-org/terraform-images).
```yaml ```yaml
image: image: registry.gitlab.com/gitlab-org/terraform-images/stable:latest
name: hashicorp/terraform:light
entrypoint:
- '/usr/bin/env'
- 'PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
``` ```
1. In the `.gitlab-ci.yaml` file, define some environment variables to ease development. In this 1. In the `.gitlab-ci.yaml` file, define some environment variables to ease
example, `GITLAB_TF_ADDRESS` is the URL of the GitLab instance where this pipeline development. In this example, `TF_STATE` is the name of the Terraform state
runs, and `TF_ROOT` is the directory where the Terraform commands must be executed: (projects may have multiple states), `TF_ADDRESS` is the URL to the state on
the GitLab instance where this pipeline runs, and `TF_ROOT` is the directory
where the Terraform commands must be executed:
```yaml ```yaml
variables: variables:
GITLAB_TF_ADDRESS: ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/terraform/state/${CI_PROJECT_NAME} TF_STATE: ${CI_PROJECT_NAME}
TF_ADDRESS: ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/terraform/state/${TF_STATE}
TF_ROOT: ${CI_PROJECT_DIR}/environments/cloudflare/production TF_ROOT: ${CI_PROJECT_DIR}/environments/cloudflare/production
cache: cache:
key: ${TF_STATE}
paths: paths:
- .terraform - ${TF_ROOT}/.terraform
``` ```
1. In a `before_script`, pass a `terraform init` call containing configuration parameters 1. In a `before_script`, change to your `TF_ROOT`:
corresponding to variables required by the
[HTTP backend](https://www.terraform.io/docs/backends/types/http.html):
```yaml ```yaml
before_script: before_script:
- cd ${TF_ROOT} - cd ${TF_ROOT}
- terraform --version
- terraform init -backend-config="address=${GITLAB_TF_ADDRESS}" -backend-config="lock_address=${GITLAB_TF_ADDRESS}/lock" -backend-config="unlock_address=${GITLAB_TF_ADDRESS}/lock" -backend-config="username=gitlab-ci-token" -backend-config="password=${CI_JOB_TOKEN}" -backend-config="lock_method=POST" -backend-config="unlock_method=DELETE" -backend-config="retry_wait_min=5"
stages: stages:
- prepare
- validate - validate
- build - build
- test
- deploy - deploy
init:
stage: prepare
script:
- gitlab-terraform init
validate: validate:
stage: validate stage: validate
script: script:
- terraform validate - gitlab-terraform validate
plan: plan:
stage: build stage: build
script: script:
- terraform plan - gitlab-terraform plan
- terraform show - gitlab-terraform plan-json
artifacts:
name: plan
paths:
- ${TF_ROOT}/plan.cache
reports:
terraform: ${TF_ROOT}/plan.json
apply: apply:
stage: deploy stage: deploy
environment: environment:
name: production name: production
script: script:
- terraform apply - gitlab-terraform apply
dependencies: dependencies:
- plan - plan
when: manual when: manual
...@@ -160,8 +171,9 @@ to the repository. ...@@ -160,8 +171,9 @@ to the repository.
- master - master
``` ```
1. Push your project to GitLab, which triggers a CI job pipeline. This pipeline runs 1. Push your project to GitLab, which triggers a CI job pipeline. This pipeline
the `terraform init`, `terraform validate`, and `terraform plan` commands. runs the `gitlab-terraform init`, `gitlab-terraform validate`, and
`gitlab-terraform plan` commands.
The output from the above `terraform` commands should be viewable in the job logs. The output from the above `terraform` commands should be viewable in the job logs.
...@@ -176,15 +188,18 @@ you can expose details from `terraform plan` runs directly into a merge request ...@@ -176,15 +188,18 @@ you can expose details from `terraform plan` runs directly into a merge request
enabling you to see statistics about the resources that Terraform will create, enabling you to see statistics about the resources that Terraform will create,
modify, or destroy. modify, or destroy.
Let's explore how to configure a GitLab Terraform Report artifact: Let's explore how to configure a GitLab Terraform Report artifact. You can
either use a pre-built image which includes a `gitlab-terraform` helper as
above, where `gitlab-terraform plan-json` outputs the required artifact, or you
can configure this manually as follows:
1. For simplicity, let's define a few reusable variables to allow us to 1. For simplicity, let's define a few reusable variables to allow us to
refer to these files multiple times: refer to these files multiple times:
```yaml ```yaml
variables: variables:
PLAN: plan.tfplan PLAN: plan.cache
PLAN_JSON: tfplan.json PLAN_JSON: plan.json
``` ```
1. Install `jq`, a 1. Install `jq`, a
...@@ -216,7 +231,8 @@ Let's explore how to configure a GitLab Terraform Report artifact: ...@@ -216,7 +231,8 @@ Let's explore how to configure a GitLab Terraform Report artifact:
terraform: $PLAN_JSON terraform: $PLAN_JSON
``` ```
For a full example, see [Example `.gitlab-ci.yaml` file](#example-gitlab-ciyaml-file). For a full example using the pre-built image, see [Example `.gitlab-ci.yaml`
file](#example-gitlab-ciyaml-file).
For an example displaying multiple reports, see [`.gitlab-ci.yaml` multiple reports file](#mulitple-terraform-plan-reports). For an example displaying multiple reports, see [`.gitlab-ci.yaml` multiple reports file](#mulitple-terraform-plan-reports).
...@@ -232,63 +248,60 @@ Let's explore how to configure a GitLab Terraform Report artifact: ...@@ -232,63 +248,60 @@ Let's explore how to configure a GitLab Terraform Report artifact:
### Example `.gitlab-ci.yaml` file ### Example `.gitlab-ci.yaml` file
```yaml ```yaml
image: image: registry.gitlab.com/gitlab-org/terraform-images/stable:latest
name: hashicorp/terraform:light
entrypoint:
- '/usr/bin/env'
- 'PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
# Default output file for Terraform plan
variables: variables:
GITLAB_TF_ADDRESS: ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/terraform/state/${CI_PROJECT_NAME} TF_STATE: ${CI_PROJECT_NAME}
PLAN: plan.tfplan TF_ADDRESS: ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/terraform/state/${TF_STATE}
PLAN_JSON: tfplan.json TF_ROOT: ${CI_PROJECT_DIR}/environments/cloudflare/production
TF_ROOT: ${CI_PROJECT_DIR}
cache: cache:
key: ${TF_STATE}
paths: paths:
- .terraform - ${TF_ROOT}/.terraform
before_script: before_script:
- apk --no-cache add jq
- alias convert_report="jq -r '([.resource_changes[]?.change.actions?]|flatten)|{\"create\":(map(select(.==\"create\"))|length),\"update\":(map(select(.==\"update\"))|length),\"delete\":(map(select(.==\"delete\"))|length)}'"
- cd ${TF_ROOT} - cd ${TF_ROOT}
- terraform --version
- terraform init -backend-config="address=${GITLAB_TF_ADDRESS}" -backend-config="lock_address=${GITLAB_TF_ADDRESS}/lock" -backend-config="unlock_address=${GITLAB_TF_ADDRESS}/lock" -backend-config="username=${GITLAB_USER_LOGIN}" -backend-config="password=${GITLAB_TF_PASSWORD}" -backend-config="lock_method=POST" -backend-config="unlock_method=DELETE" -backend-config="retry_wait_min=5"
stages: stages:
- prepare
- validate - validate
- build - build
- deploy - deploy
init:
stage: prepare
script:
- gitlab-terraform init
validate: validate:
stage: validate stage: validate
script: script:
- terraform validate - gitlab-terraform validate
plan: plan:
stage: build stage: build
script: script:
- terraform plan -out=$PLAN - gitlab-terraform plan
- terraform show --json $PLAN | convert_report > $PLAN_JSON - gitlab-terraform plan-json
artifacts: artifacts:
name: plan
paths:
- ${TF_ROOT}/plan.cache
reports: reports:
terraform: ${TF_ROOT}/tfplan.json terraform: ${TF_ROOT}/plan.json
# Separate apply job for manual launching Terraform as it can be destructive
# action.
apply: apply:
stage: deploy stage: deploy
environment: environment:
name: production name: production
script: script:
- terraform apply -input=false $PLAN - gitlab-terraform apply
dependencies: dependencies:
- plan - plan
when: manual when: manual
only: only:
- master - master
``` ```
### Mulitple Terraform Plan reports ### Mulitple Terraform Plan reports
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment