Terrakube support to customize the job workflow for an specific workspace using external tools.
The workflow is built with the Terrakube Configuration Language using a YAML file
The standard job workflow looks like the following example:
flow:
- type: "terraformPlan"
step: 100
- type: "terraformApply"
step: 200
If you want to customize the job workflow we can add commands using Groovy or Bash and execute user defined actions.
flow:
- type: "terraformPlan"
step: 100
commands:
- runtime: "GROOVY"
priority: 100
before: true
script: |
import TerraTag
new TerraTag().downloadTerraTag("$workingDirectory", "0.1.29", "darwin", "amd64")
"TerraTag Download Compledted..."
- runtime: "BASH"
priority: 200
before: true
script: |
echo $PATH
helloWorld.sh
terratag.sh
- type: "terraformApply"
step: 300
At runtime while executing a job workspace the groovy clases and bash scripts are loaded inside the job context so you can execute user defined actions.
During runtime all the bash scripts inside the folder bash for this repository are loaded inside the job context, so we can call different scripts like the following example
flow:
- type: "customScripts"
step: 100
commands:
- runtime: "BASH"
priority: 200
before: true
script: |
helloWorld.sh
terratag.sh
- type: "terraformApply"
step: 300
All bash scripts should end with extension ".sh"
During runtime all the groovy classes are loaded inside the job context, we can import it using an import statement like the following example:
flow:
- type: "terraformPlan"
step: 100
commands:
- runtime: "GROOVY"
priority: 100
before: true
script: |
import TerraTag
new TerraTag().loadTool(
"$workingDirectory",
"$bashToolsDirectory",
"0.1.30")
"Terratag download completed"
All clases should end with extension ".groovy"
By default terrakube will inject the following values inside the job context while running the user defined actions.
- bashToolsDirectory
- terrakubeToolsRepository
- workingDirectory
- organizationId
- workspaceId
- jobId
- stepId
- terraformVersion
- source
- branch
- vcsType
- accessToken
- terraformOutput
- terrakubeApi
- terrakubeToken
- workspace variables
- workspace environment variables
if you are using the Bash runtime this fields will be available as environment variables, for Groovy this values are injecte as bindings that can be access using the groovy syntax with $ character
Example 1: Writing all the custom logic in groovy and bash with fields injection
flow:
- type: "terraformPlan"
step: 100
commands:
- runtime: "GROOVY"
priority: 100
before: true
script: |
@Grapes([
@Grab('commons-io:commons-io:2.8.0'),
@Grab('org.apache.commons:commons-compress:1.21'),
])
import org.apache.commons.io.FileUtils
class TerraTagDownloader {
def downloadTerraTag(workingDirectory, version, os, arch) {
String terraTagFile = "terratag_${version}_${os}_${arch}.tar.gz"
String terraTagURL = "https://github.com/env0/terratag/releases/download/v${version}/${terraTagFile}"
println "Downloading $terraTagURL"
FileUtils.copyURLToFile(new URL(terraTagURL), new File("${workingDirectory}/${terraTagFile}"))
}
}
new TerraTagDownloader().downloadTerraTag("$workingDirectory", "0.1.29", "darwin", "amd64")
"TerraTag Download Compledted..."
- runtime: "BASH"
priority: 200
before: true
script: |
cd $workingDirectory;
tar -xvf terratag_0.1.29_darwin_amd64.tar.gz;
chmod +x terratag;
./terratag -tags="{\"environment_id\": \"development\"}"
- type: "terraformApply"
step: 300
- type: "terraformDestroy"
step: 400
Example 2: Reusing exiting Terrakube extension to simplify the flow
flow:
- type: "terraformPlan"
step: 100
commands:
- runtime: "GROOVY"
priority: 100
before: true
script: |
import TerraTag
new TerraTag().loadTool(
"$workingDirectory",
"$bashToolsDirectory",
"0.1.30")
"Terratag download completed"
- runtime: "BASH"
priority: 200
before: true
script: |
cd $workingDirectory
terratag -tags="{\"environment_id\": \"development\"}"
- type: "terraformApply"
step: 300
Example 3: Handle terraform output after terraform apply
flow:
- type: "terraformPlan"
step: 100
commands:
- runtime: "GROOVY"
priority: 100
before: true
script: |
import TerraTag
new TerraTag().loadTool(
"$workingDirectory",
"$bashToolsDirectory",
"0.1.30")
"Terratag download completed"
- runtime: "BASH"
priority: 200
before: true
script: |
cd $workingDirectory
terratag -tags="{\"environment_id\": \"development\"}"
- type: "terraformApply"
step: 200
commands:
- runtime: "GROOVY"
priority: 100
after: true
script: |
import groovy.json.JsonSlurper
def jsonSlurper = new JsonSlurper()
def terraformOutput = jsonSlurper.parseText("$terraformOutputJson")
terrakubeOutput << "This is the name of the RG ${terraformOutput.rg_name.value}"
- type: "terraformDestroy"
step: 400
Example 4: Handle approvals inside jobs
flow:
- type: "terraformPlan"
step: 100
commands:
- runtime: "GROOVY"
priority: 100
before: true
script: |
import TerraTag
new TerraTag().loadTool(
"$workingDirectory",
"$bashToolsDirectory",
"0.1.30")
"Terratag download completed"
- runtime: "BASH"
priority: 200
before: true
script: |
cd $workingDirectory
terratag -tags="{\"environment_id\": \"development\"}"
- type: "approval"
step: 150
team: "AZB_ADMIN"
- type: "terraformApply"
step: 200
commands:
- runtime: "GROOVY"
priority: 100
after: true
script: |
import groovy.json.JsonSlurper
def jsonSlurper = new JsonSlurper()
def terraformOutput = jsonSlurper.parseText("$terraformOutputJson")
terrakubeOutput << "This is the name of the RG ${terraformOutput.rg_name.value}"
- type: "approval"
step: 250
team: "AZB_ADMIN"
- type: "terraformDestroy"
step: 300
Terrakube extension support the following tools:
- Terratag (Groovy Extension)
- Infracost (Groovy Extension)
- Terrascan (Groovy Extension)
- SendGrid (Groovy Extension)
- Snyk (Groovy Extension)
- Slack (Groovy Extension)
- Open Policy Agent (Groovy Extension)
- Teams
If you want to integrate terrakube extension with other tools feel free to create a fork and send a pull request to this repository