Terraform Cloud Actions
Port's Terraform Cloud integration allows you to trigger Terraform Cloud runs directly from Port.
Overviewโ
You can implement this action in two ways:
- Synced webhook and secrets: A simpler approach that uses Port's secret management to store your Terraform Cloud credentials.
- Execution agent: A slightly more complex approach that runs within your infrastructure, keeping credentials in your environment.
Prerequisitesโ
-
A Terraform Cloud User token or Team token.
Terraform Cloud run endpointNote: Terraform Cloud run endpoint cannot be accessed with organization tokens. You must access it with a user token or team token.
-
If you choose to implement using the Execution Agent, you will need to:
Set up data modelโ
Before implementing either approach, you'll need to create a blueprint for Terraform Cloud workspaces:
-
Go to your Builder page.
-
Click on
+ Blueprint
. -
Click on the
{...}
button in the top right corner, and choose "Edit JSON". -
Add this JSON schema:
Terraform Cloud workspace blueprint
{
"identifier": "terraform_cloud_workspace",
"title": "Terraform Cloud Workspace",
"icon": "Terraform",
"schema": {
"properties": {
"workspace_id": {
"title": "Workspace Id",
"type": "string"
},
"organization_name": {
"title": "Organization Name",
"type": "string"
},
"workspace_name": {
"title": "Workspace Name",
"type": "string"
}
},
"required": ["workspace_id", "organization_name", "workspace_name"]
},
"mirrorProperties": {},
"calculationProperties": {},
"relations": {}
} -
Click
Save
to create the blueprint.
Implementationโ
- Synced webhook
- Execution agent
You can trigger Terraform Cloud runs by leveraging Port's synced webhooks to directly interact with the Terraform Cloud API and secrets to store your Terraform Cloud credentials. This method simplifies the setup by handling everything within Port.
Add Port secrets
To add Terraform Cloud credentials to your portal:
-
Click on the
...
button in the top right corner of your Port application. -
Click on Credentials.
-
Click on the
Secrets
tab. -
Click on
+ Secret
and add:TF_TOKEN
: Your Terraform Cloud user or team token
Create Terraform Cloud self-service action
To create a self-service action that triggers a Terraform Cloud run, follow these steps:
-
Head to the self-service page.
-
Click on the
+ New Action
button. -
Click on the
{...} Edit JSON
button. -
Copy and paste the following JSON configuration into the editor.
Trigger TF Cloud Run action
{
"identifier": "terraform_cloud_workspace_trigger_run",
"title": "Trigger TF Cloud Run",
"icon": "Terraform",
"trigger": {
"type": "self-service",
"operation": "DAY-2",
"userInputs": {
"properties": {
"is_destroy": {
"title": "Is Destroy",
"type": "boolean",
"default": false
},
"message": {
"title": "Message",
"type": "string",
"default": "Triggered via Port"
},
"variables": {
"title": "Variables",
"type": "object",
"default": {}
}
},
"required": ["message"],
"order": ["message", "is_destroy", "variables"]
},
"blueprintIdentifier": "terraform_cloud_workspace"
},
"invocationMethod": {
"type": "WEBHOOK",
"url": "https://app.terraform.io/api/v2/runs",
"agent": false,
"synchronized": true,
"method": "POST",
"headers": {
"Authorization": "Bearer {{.secrets.TF_TOKEN}}",
"Content-Type": "application/vnd.api+json"
},
"body": {
"data": {
"attributes": {
"is-destroy": "{{.inputs.is_destroy}}",
"message": "{{.inputs.message}}",
"variables": "{{.inputs.variables | toTFVariables}}"
},
"type": "runs",
"relationships": {
"workspace": {
"data": {
"type": "workspaces",
"id": "{{.entity.properties.workspace_id}}"
}
}
}
}
}
},
"requiredApproval": false
} -
Click
Save
.
Now you should see the Trigger TF Cloud Run
action in the self-service page. ๐
The Execution Agent approach runs an agent within your infrastructure that connects to Port via Kafka, keeping your credentials secure within your environment.
The steps are as follows:
- Port publishes an invoked
Action
message containing the run details to a topic. - A secure topic (
ORG_ID.runs
) holds all the action invocations. - Port's execution agent pulls the new trigger event from your Kafka topic and triggers your Terraform Cloud run.
Create Terraform Cloud self-service action
To create a self-service action that triggers a Terraform Cloud run, follow these steps:
-
Head to the self-service page.
-
Click on the
+ New Action
button. -
Click on the
{...} Edit JSON
button. -
Copy and paste the following JSON configuration into the editor.
Trigger TF Cloud run Action
{
"identifier": "terraform_cloud_workspace_trigger_tf_run",
"title": "Trigger TF Cloud run",
"icon": "Terraform",
"trigger": {
"type": "self-service",
"operation": "DAY-2",
"userInputs": {
"properties": {},
"required": [],
"order": []
},
"blueprintIdentifier": "terraform_cloud_workspace"
},
"invocationMethod": {
"type": "WEBHOOK",
"url": "https://app.terraform.io/api/v2/runs/",
"agent": true,
"synchronized": false,
"method": "POST",
"body": {
"action": "{{ .action.identifier[(\"terraform_cloud_workspace_\" | length):] }}",
"resourceType": "run",
"status": "TRIGGERED",
"trigger": "{{ .trigger | {by, origin, at} }}",
"context": {
"entity": "{{.entity.identifier}}",
"blueprint": "{{.action.blueprint}}",
"runId": "{{.run.id}}"
},
"payload": {
"entity": "{{ (if .entity == {} then null else .entity end) }}",
"action": {
"invocationMethod": {
"type": "WEBHOOK",
"agent": true,
"synchronized": false,
"method": "POST",
"url": "https://app.terraform.io/api/v2/runs/"
},
"trigger": "{{.trigger.operation}}"
},
"properties": {},
"censoredProperties": "{{.action.encryptedProperties}}"
}
}
},
"requiredApproval": false
} -
Click
Save
.
Now you should see the Trigger TF Cloud run
action in the self-service page. ๐
Create the invocations.json mapping
Create a JSON file named invocations.json
with the following content:
Mapping (invocations.json)
[
{
"enabled": ".action == \"trigger_tf_run\"",
"headers": {
"Authorization": "\"Bearer \" + env.TF_TOKEN",
"Content-Type": "\"application/vnd.api+json\""
},
"body": {
"data": {
"attributes": {
"is-destroy": false,
"message": "\"Triggered via Port\"",
"variables": ".payload.properties | to_entries | map({key: .key, value: .value})"
},
"type": "\"runs\"",
"relationships": {
"workspace": {
"data": {
"type": "\"workspaces\"",
"id": ".payload.entity.properties.workspace_id"
}
}
}
}
},
"report": {
"status": "if .response.statusCode == 201 then \"SUCCESS\" else \"FAILURE\" end",
"link": "\"https://app.terraform.io/app/\" + .body.payload.entity.properties.organization_name + \"/workspaces/\" + .body.payload.entity.properties.workspace_name + \"/runs/\" + .response.json.data.id",
"externalRunId": ".response.json.data.id"
}
}
]
Install execution agent
-
Add Port's Helm repo:
helm repo add port-labs https://port-labs.github.io/helm-charts
Already existing repoIf you already added this repo earlier, run
helm repo update
to retrieve the latest versions of the charts. You can then runhelm search repo port-labs
to see the charts. -
Install the
port-agent
chart:helm install my-port-agent port-labs/port-agent \
--create-namespace --namespace port-agent \
--set-file controlThePayloadConfig=./invocations.json \
--set env.normal.PORT_ORG_ID=YOUR_ORG_ID \
--set env.normal.KAFKA_CONSUMER_GROUP_ID=YOUR_KAFKA_CONSUMER_GROUP \
--set env.secret.PORT_CLIENT_ID=YOUR_PORT_CLIENT_ID \
--set env.secret.PORT_CLIENT_SECRET=YOUR_PORT_CLIENT_SECRET \
--set env.secret.TF_TOKEN=YOUR_TERRAFORM_CLOUD_TOKEN
Let's test it!โ
-
Head to the self-service page of your portal
-
Click on the Terraform Cloud run action you created
-
Fill in the run details:
- Message describing the purpose of the run
- Whether this is a destroy operation
- Any variables needed for the Terraform run
-
Click on
Execute
-
Wait for the run to be triggered in Terraform Cloud
-
Check your Terraform Cloud workspace page to see the new run