# Configure the pipeline to run Terraform plan

Pipeline step3

To complete this step, we will use what we previously saw in the Step 2 by adding a new job to run Terraform if our unittest succeed. The goal is to configure a new resource to run Terraform and use it in a dedicated job. Additionally to that, the Terraform code will be stored into our Git repository, inside the stacks branch. Which means that we will also configure a git resource in the pipeline to get the content of the stacks branch.

Follow those steps to apply all changes described in this step

Starting with the Terraform code. Let's create a dummy Terraform configuration which only specifies they Cloud provider we cant to use Azure provider for Terraform in a provider.tf file.

TIP

If you are not comfortable with Terraform, we encourage you to follow Terraform getting started documentation.

The content of the provider.tf specifies the usage of azure provider and also input variables to configure it. Those variables will be provided by the pipeline.

stack-sample/terraform/provider.tf

Several input variables have been defined to configure the Cloud provider and two variable to with pass the url of the source code git repository that we will use and explain in the next step. The provider.tf usually also contain some generic variables like customer, project and env by default as most of our customer use them in Terraform to tag/name Cloud components.

Now add a Terraform resource into the pipeline. As Terraform is not part of the core resources type of Concourse, the first thing is to specify a new terraform resource type in the dedicated root section resource_types.

TIP

When to use a task or a resource in a pipeline ? In our case, we could have provided our own container image with Terraform already installed on it, and call the terraform command. A resource usually is here to simplify a task, it makes something more generic and easy to use with embedded scripts. A resource also creates versions which can be used between different jobs as trigger. If you are interested to create your own resource, follow https://concourse-ci.org/implementing-resource-types.html documentation.

stack-sample/pipeline/pipeline.yml





 


resource_types:
  - name: terraform
    type: docker-image
    source:
      repository: ljfranklin/terraform-resource
      tag: '0.12.24'
1
2
3
4
5
6

The source code of this resource can be found here.

From there, a new terraform resource type is available and can be configured. The following sample configure a resource called tfstate of our new terraform type:

stack-sample/pipeline/pipeline.yml

Some explanations: Terraform store the status of the infrastructure in a file called tfstate. This file can be store in different backends. In this example we decided to use our cloud provider object store as backend type to store this file. This is defined by the backend_type parameter, then configured in the backend_config section, using pipeline variables defined below. To know more about the configuration for your backend storage, refer to the dedicated Terraform documentation.

The vars section define a collection of Terraform input variables provided by the pipeline. Literally variables given by the pipeline to Terraform. The most common one are the Cloud provider credentials that we defined in provider.tf and also the extra customer/project/env that we saw previously.

Small detour by variables.sample.yml file to add our new pipeline variables:

stack-sample/pipeline/variables.sample.yml

We added several variables related to our pipeline changes.

  • git: to provide the SSH key to use to get Terraform code from your private git repository (git_ssh_key). As well as the branch and url to use (stack_git_branch, git_repository)
  • cloud provider: to configure the cloud provider access and Terraform tfstate file storage.

As you can see the value of some variables have a specific format ((myvalue)) for example line 1, It mean the value of this pipeline variable will be provided by a Cycloid credential. They one you created in the following section prepare cycloid credentials section. See Vault in the pipeline documentation for more information to use Cycloid credentials into a pipeline.

Getting back on the pipeline file to configure a git resource to get the dummy Terraform source code from our stacks branch.

stack-sample/pipeline/pipeline.yml










 

resources:
...
- name: git_stack
  type: git
  source:
    uri: ((git_repository))
    branch: ((stack_git_branch))
    private_key: ((git_ssh_key))
    paths:
      - stack-sample/terraform/*
1
2
3
4
5
6
7
8
9
10

We also added a filter on terraform path using paths to trigger terraform jobs only when commits changes terraform files.

Common pipeline behavior with terraform is to run terraform plan, it's a convenient way to check whether the execution plan for a set of changes matches your expectations without making any changes to real resources. Then create a second job to apply those changes by calling terraform apply.

Let's start and create the dedicated job to run terraform plan command just after unittest job (passed argument) and speak about terraform apply in the next step:

stack-sample/pipeline/pipeline.yml








 

 


 


 


jobs:
...
  - name: terraform-plan
    max_in_flight: 1
    build_logs_to_retain: 10
    plan:
      - do:
        - get: git_stack
          trigger: true
        - get: git_code
          trigger: true
          passed:
            - unittest
        - put: tfstate
          params:
            plan_only: true
            terraform_source: git_stack/stack-sample/terraform
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

An important point is the passed parameter that you can put on get action. This keyword links jobs together to ensure that we will get the code which was already processed by the unittest job.

This job gets Terraform code from git_stack resource which is our git on the stacks branch. Then call put on Terraform resource (tfstate) using plan_only parameter to specify that we want to only run terraform plan.

Don't forget to add this job to a group:

stack-sample/pipeline/pipeline.yml





 

groups:
- name: overview
  jobs:
  - unittest
  - terraform-plan
1
2
3
4
5

Click on the terraform-plan job and see Terraform logs saying we successfully run it with 0 changes.

Terraform

Add and commit those changes in Git:

git add .
git commit -m "Step 3"
git push origin stacks
1
2
3

Get back to Cycloid's dashboard, click on the Refresh pipeline button Refresh pipeline.