Using Terraform modules in Environments

Terraform modules can be used in Bunnyshell in the form of an Environment Component which acts like a runner for the Terraform commands, and also has some conventions in place to handle created resources.

📘

Example

In order to understand how Terraform modules integrate with other Components in Bunnyshell Environments, let's take a look at a concrete example: we will study the Demo Books bunnyshell.yaml, with a Terraform Component added.

You can find the repo here.

Let's take a look at the Terraform Components and go through the declaration of the Terraform kind.

components:
	  ...
    -
        kind: Terraform
        name: s3-bucket
        gitRepo: 'https://github.com/bunnyshell/demo-books.git'
        gitBranch: terraform
        gitApplicationPath: /backend/_terraform
        runnerImage: 'hashicorp/terraform:1.5.1'
        deploy:
            - 'cd backend/_terraform'
            - '/bns/helpers/terraform/get_managed_backend > zz_backend_override.tf'
            - 'terraform init -input=false -no-color'
            - 'terraform apply -var "bucket_name=demo-{{ env.unique }}" -input=false -auto-approve -no-color'
            - 'BNS_TF_STATE_LIST=`terraform show -json`'
            - 'BUCKET_NAME=`terraform output --raw s3_bucket_name`'
            - 'BUCKET_REGION=`terraform output --raw s3_bucket_region`'
        destroy:
            - 'cd backend/_terraform'
            - '/bns/helpers/terraform/get_managed_backend > zz_backend_override.tf'
            - 'terraform init -input=false -no-color'
            - 'terraform destroy -var "bucket_name=demo-{{ env.unique }}" -input=false -auto-approve -no-color'
        exportVariables:
            - BUCKET_NAME
            - BUCKET_REGION
        environment:
            AWS_ACCESS_KEY_ID: your-key
            AWS_REGION: your-region
            AWS_SECRET_ACCESS_KEY: your-secret

📘

AWS Credentials

In order for the module to be able to create the S3 bucket, it needs AWS access with correct privileges.

The environment variables needed are:
AWS_ACCESS_KEY_ID: your-key
AWS_REGION: your-region
AWS_SECRET_ACCESS_KEY: your-secret

They can either be specified at Component level, in the environment attribute, or inherited from the environment level, environmentVariables top-level attribute.

Within the repository, the Terraform module can be found within the folder /backend/_terraform.

Having the gitApplicationPath set to this value ensures that if files inside this folder change, Bunnyshell will be aware and can trigger Environment updates (if the settings require this).

The scripts within deploy and destroy attributes will be ran inside a container started from the runnerImage attribute's value. Inside the container, the whole git repository indicated by gitRepo will be cloned in the working directory, with the contents dictated by gitBranch.


Creating the resources

When the Environment is deployed, the scripts from the deploy attribute are ran, in sequence. An exit code different than 0 causes the execution to stop and the deployment to be considered as failed. Please see Troubleshooting for more information.

First, we navigate into the Terraform module's folder.

Next, we set the Terraform backend (to preserve the state) to the one provided by Bunnyshell. Feel free to discard this line and use your own backend.

Then, in a standard manner, terraform init and terraform apply are called, passing some variables. The contents of the variables can be interpolated, check out the Variable Interpolation section for details on how to leverage other variables's contents.

Running BNS_TF_STATE_LIST=terraform show -json` after applying is very important, because this is the mechanism through which Bunnyshell becomes aware of the resources created by Terraform, so it can list them and display details about them as well.

Lastly, we notice two variables being set: BUCKET_NAME and BUCKET_REGION. These will be exported in order to be used by other Components of the Environment, through interpolation: {{ components.s3-bucket.exported.BUCKET_NAME }} and {{ components.s3-bucket.exported.BUCKET_REGION }}.


Deleting the resources

When the Environment is deleted, the scripts from the destroy attribute are ran, in sequence. An exit code different than 0 causes the execution to stop and the deletion to be considered as failed. Please see Troubleshooting for more information.

The commands under the destroy attribute are very similar to the ones in deploy, except these will delete the resources stored in the Terraform state.


Seeing the results

You can see the output of the ran scripts in the Pipelines. As you may have noticed, the scripts were ran with -no-color in order to produce a plain output, easily readable within logs.