Managing Union resources with Terraform

The Union Terraform provider enables you to manage Union resources using infrastructure-as-code principles. This page provides an overview of the provider’s capabilities, including authentication, available resources, and data sources.

Provider configuration

Basic configuration

Configure the Union provider in your Terraform configuration:

terraform {
  required_providers {
    unionai = {
      source  = "unionai/unionai"
      version = "~> 0.2"
    }
  }
}

provider "unionai" {
  api_key      = var.unionai_api_key
  allowed_orgs = ["your-org-name"]
}

Configuration parameters

  • api_key (Required): Your Union API key for authentication
  • allowed_orgs (Optional): List of organization names to restrict operations to, preventing unintended operations across multiple organizations

Authentication

The Union Terraform provider uses API key authentication. You can provide your API key in two ways:

1. Provider configuration

Specify the API key directly in the provider block (use variables to avoid hardcoding):

provider "unionai" {
  api_key = var.unionai_api_key
}

2. Environment variable

Set the UNIONAI_API_KEY environment variable:

export UNIONAI_API_KEY="your-api-key"

Generating an API key

Create an API key using the flyte CLI:

flyte create api-key --name "terraform-api-key"

For more information on creating API keys, see the Flyte CLI documentation.

Save the generated key securely, as it will be used to authenticate all Terraform operations against your Union deployment.

Available resources

The Union Terraform provider supports the following resources for managing your Union deployment:

Projects

Create and manage Union projects:

resource "unionai_project" "example" {
  name        = "my-project"
  description = "Example project managed by Terraform"
}

Projects are the primary organizational unit in Union, containing workflows, tasks, and executions.

Users

Manage user accounts:

resource "unionai_user" "example" {
  email      = "[email protected]"
  first_name = "John"
  last_name  = "Doe"
}

Roles

Define custom roles for access control:

resource "unionai_role" "example" {
  name        = "custom-role"
  description = "Custom role with specific permissions"
  actions = [
    "create_flyte_executions",
    "view_flyte_inventory",
  ]
}

The actions argument is required: it is the set of actions the role grants (for example, create_flyte_executions, register_flyte_inventory, administer_project).

Policies

Create access policies that define permissions:

resource "unionai_policy" "example" {
  name        = "project-access-policy"
  description = "Policy for project access"

  project {
    id      = unionai_project.example.id
    role_id = unionai_role.example.id
    domains = ["development", "staging"]
  }
}

A policy binds a role to a subject at a given scope. Use an organization, project, or domain block (each takes an id and a role_id); the project block also accepts an optional domains set.

API keys

Generate and manage API keys programmatically:

resource "unionai_api_key" "example" {
  id = "automation-key"
}

The id is the only argument; it must be unique within your organization. The generated secret is a read-only, sensitive attribute stored in state, available only at creation time.

OAuth applications

Configure OAuth applications for external integrations:

resource "unionai_application" "example" {
  client_id   = "external-app"
  client_name = "External Application"

  grant_types   = ["AUTHORIZATION_CODE"]
  redirect_uris = ["https://example.com/callback"]
}

The required arguments are client_id and client_name. redirect_uris is a set of strings (not a single value). The client secret is a read-only, sensitive attribute available only at creation time.

Access assignments

Access is policy-based: a policy carries the role-to-scope binding, and an access resource assigns that policy to a user or an application. Each access resource takes just two arguments.

# Assign a policy to a user
resource "unionai_user_access" "example" {
  user_id   = unionai_user.example.id
  policy_id = unionai_policy.example.id
}

# Assign a policy to an application
resource "unionai_application_access" "example" {
  app_id    = unionai_application.example.id
  policy_id = unionai_policy.example.id
}

Available data sources

Data sources allow you to query existing Union resources for use in your Terraform configuration. Each is looked up by its id; attributes such as name and email are read-only outputs, not lookup keys.

Projects

Query an existing project:

data "unionai_project" "existing" {
  id = "my-project-id"
}

Users

Look up user information:

data "unionai_user" "existing" {
  id = "user-id"
}

Roles

Reference an existing role:

data "unionai_role" "admin" {
  id = "admin-role-id"
}

Policies

Query an existing policy:

data "unionai_policy" "existing" {
  id = "policy-id"
}

API keys

Reference an existing API key:

data "unionai_api_key" "existing" {
  id = "api-key-id"
}

Applications

Look up an OAuth application:

data "unionai_application" "existing" {
  id = "app-client-id"
}

Data plane information

Query information about the data plane:

data "unionai_dataplane" "current" {
  id = "dataplane-id"
}

Control plane information

Access control plane details:

data "unionai_controlplane" "current" {
  # Control plane data source
}

Data plane listings

List all available data planes:

data "unionai_dataplanes" "all" {
  # Returns list of all data planes
}

Best practices

Use variables for sensitive data

Never hardcode sensitive information like API keys in your Terraform files:

variable "unionai_api_key" {
  description = "Union API key"
  type        = string
  sensitive   = true
}

provider "unionai" {
  api_key = var.unionai_api_key
}

Organize resources with modules

Structure your Terraform code using modules for reusability:

terraform/
├── modules/
│   ├── project/
│   │   ├── main.tf
│   │   ├── variables.tf
│   │   └── outputs.tf
│   └── access-control/
│       ├── main.tf
│       ├── variables.tf
│       └── outputs.tf
└── main.tf

Use organization restrictions

Prevent accidental operations across multiple organizations:

provider "unionai" {
  api_key      = var.unionai_api_key
  allowed_orgs = ["production-org"]
}

Version control your configuration

Store your Terraform configuration in version control to track changes over time, but ensure sensitive files are excluded:

# .gitignore
*.tfvars
*.tfstate
*.tfstate.backup
.terraform/

Use remote state

For team environments, use remote state storage:

terraform {
  backend "s3" {
    bucket = "my-terraform-state"
    key    = "union/terraform.tfstate"
    region = "us-west-2"
  }
}

Example: complete setup

Here’s a complete example that creates a project with access control:

terraform {
  required_providers {
    unionai = {
      source  = "unionai/unionai"
      version = "~> 0.2"
    }
  }
}

provider "unionai" {
  api_key      = var.unionai_api_key
  allowed_orgs = ["my-organization"]
}

# Create a project
resource "unionai_project" "ml_pipeline" {
  name        = "ml-pipeline"
  description = "Machine learning pipeline project"
}

# Create a custom role
resource "unionai_role" "ml_engineer" {
  name        = "ml-engineer"
  description = "Role for ML engineers"
  actions = [
    "create_flyte_executions",
    "view_flyte_inventory",
  ]
}

# Create a user
resource "unionai_user" "data_scientist" {
  first_name = "Jane"
  last_name  = "Smith"
  email      = "[email protected]"
}

# Bind the role to the project with a policy
resource "unionai_policy" "ml_pipeline_access" {
  name        = "ml-pipeline-access"
  description = "Grant the ML engineer role on the ML pipeline project"

  project {
    id      = unionai_project.ml_pipeline.id
    role_id = unionai_role.ml_engineer.id
  }
}

# Assign the policy to the user
resource "unionai_user_access" "scientist_access" {
  user_id   = unionai_user.data_scientist.id
  policy_id = unionai_policy.ml_pipeline_access.id
}

# Create an API key for automation
resource "unionai_api_key" "ci_cd" {
  id = "ci-cd-pipeline-key"
}

Additional resources

Requirements

  • Terraform: >= 1.0
  • Union API key: Generated via the flyte CLI
  • Go: >= 1.24 (for development only)

Support and contributions

The Union Terraform provider is open source and licensed under the Mozilla Public License 2.0. For the complete provider documentation, visit the Terraform Registry.