Skip to main content

Manage integration mapping using Terraform

In this example we'll use the Import State feature of Terraform, then manage our Port integration's mapping with Terraform.

Prerequisites

You will need to create an integration within the Port UI, For example the Kubernetes Exporter

Installation Id

As you create the integration, take note of the installation Id.

Getting started

In order to interact with the API you will need an API token.

Getting an API token involves 2 steps:

  1. Finding your Port API credentials.
  2. Making an API request to generate a valid token.

Find your Port credentials

Get your Port credentials

To get your Port credentials, go to your Port application, click on the ... button in the top right corner, and select Credentials. Here you can view and copy your CLIENT_ID and CLIENT_SECRET:

Download your integration configuration into a file

Here are some code examples showing how to download the integration configuration in various programming languages:

#/usr/bin/env bash

# Dependencies to install:
# For apt:
# $ sudo apt-get install jq
# For yum:
# $ sudo yum install jq

INSTALLATION_ID="YOUR_INSTALLATION_ID"
CLIENT_ID="YOUR_CLIENT_ID"
CLIENT_SECRET="YOUR_CLIENT_SECRET"

ACCESS_TOKEN=$(curl -s --location -X POST 'https://api.getport.io/v1/auth/access_token' \
--header 'Content-Type: application/json' \
--data-raw """{
\"clientId\": \"${CLIENT_ID}\",
\"clientSecret\": \"${CLIENT_SECRET}\"
}""" | jq -r '.accessToken')

curl -s -X GET \
"https://api.getport.io/v1/integration/${INSTALLATION_ID}?byField=installationId" \
-H 'accept: */*' \
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
| jq '.integration.config' > ./${INSTALLATION_ID}.json

Selecting a Port API URL by account region

The baseUrl, port_region, port.baseUrl, portBaseUrl, port_base_url and OCEAN__PORT__BASE_URL parameters are used to select which instance or Port API will be used.

Port exposes two API instances, one for the EU region of Port, and one for the US region of Port.

Here is the complete main.tf file:

main.tf dependency

Notice that the main.tf file references the downloaded file generated in the previous command

See the file("${path.module}/...") function

Complete Terraform definition file
terraform {
required_providers {
port = {
source = "port-labs/port-labs"
version = "~> 2.0.3"
}
}

provider "port" {
client_id = "YOUR_CLIENT_ID" # or set the environment variable PORT_CLIENT_ID
secret = "YOUR_CLIENT_SECRET" # or set the environment variable PORT_CLIENT_SECRET
base_url = "https://api.getport.io"
}

resource "port_integration" "tf_{my-installation-id}" {
installation_id = "{my-installation-id}"
installation_app_type = "{my-installation-type}"
title = "{my-installation-title}"
version = ""
# The reason for the jsonencode|jsondecode is
# to preserve the exact syntax as terraform expects,
# this resolves conflicts in the state caused by indents
config = jsonencode(jsondecode(file("${path.module}/{my-installation-id}.json")))
}

Selecting a Port API URL by account region

The baseUrl, port_region, port.baseUrl, portBaseUrl, port_base_url and OCEAN__PORT__BASE_URL parameters are used to select which instance or Port API will be used.

Port exposes two API instances, one for the EU region of Port, and one for the US region of Port.

Let's break down the definition file and understand the different parts:

Module imports

This part includes importing and setting up the required Terraform providers and modules:

terraform {
required_providers {
port = {
source = "port-labs/port-labs"
version = "~> 2.0.3"
}
}
}

provider "port" {
client_id = "YOUR_CLIENT_ID" # or set the environment variable PORT_CLIENT_ID
secret = "YOUR_CLIENT_SECRET" # or set the environment variable PORT_CLIENT_SECRET
base_url = "https://api.getport.io"
}
Selecting a Port API URL by account region

The baseUrl, port_region, port.baseUrl, portBaseUrl, port_base_url and OCEAN__PORT__BASE_URL parameters are used to select which instance or Port API will be used.

Port exposes two API instances, one for the EU region of Port, and one for the US region of Port.

Port Terraform Provider Integration Resource

This part includes declaring the Port integration and pointing the downloaded json file as the source of the integration configuration

resource "port_integration" "tf_{my-installation-id}" {
installation_id = "{my-installation-id}"
installation_app_type = "{my-installation-type}"
title = "{my-installation-title}"
version = ""
# The reason for the jsonencode|jsondecode is
# to preserve the exact syntax as terraform expects,
# this resolves conflicts in the state caused by indents
config = jsonencode(jsondecode(file("${path.module}/{my-installation-id}.json")))
}

Terraform JSON formatting

Since Terraform is very explicit when writing and reading the state, we use jsonencode and jsondecode on the raw JSON file to make sure we do not have a conflict simply by having a bit different formatting than the Terraform JSON formatting.

To use this example yourself, simply replace the placeholders for installation_id, client_id and secret and then run the following commands to setup terraform, import the state and verifying that everything was imported:

# install modules and create an initial state
terraform init
# import state from the Port API
terraform import port_integration.tf_{my-installation-id} {my-installation-id}
# To view Terraform's planned changes based on your .tf definition file:
terraform plan

Result

After running terraform plan you should see that there are not changes from the imported state.