# Manage Union through Terraform
> This bundle contains all pages in the Manage Union through Terraform section.
> Source: https://www.union.ai/docs/v2/union/deployment/terraform/

=== PAGE: https://www.union.ai/docs/v2/union/deployment/terraform ===

# Managing Union with Terraform

> **📝 Note**
>
> An LLM-optimized bundle of this entire section is available at [`section.md`](section.md).
> This single file contains all pages in this section, optimized for AI coding agent context.

Union provides a Terraform provider that enables infrastructure-as-code management of your Union deployment. With the Union Terraform provider, you can define, deploy, and manage Union resources using declarative configuration files.

## Overview

The Union Terraform provider allows you to manage Union resources programmatically, including:

- **Projects**: Create and manage Union projects
- **Access Control**: Configure users, roles, and policies
- **API Keys**: Generate and manage API keys for automation
- **OAuth Applications**: Set up OAuth applications for external integrations
- **Access Assignments**: Assign users and applications to resources

## Why use Terraform?

Using Terraform to manage Union provides several benefits:

- **Version Control**: Track changes to your Union configuration over time
- **Reproducibility**: Easily replicate configurations across environments
- **Automation**: Integrate Union management into your CI/CD pipelines
- **Consistency**: Ensure consistent configuration across your organization
- **Documentation**: Your Terraform files serve as living documentation

## Getting Started

To get started with the Union Terraform provider:

1. **Installation**: Set up the Terraform provider in your environment
2. **Management**: Learn about the available resources and data sources for managing Union

### **Managing Union with Terraform > Installing the Union Terraform Provider**

Install and configure the Union Terraform provider

### **Managing Union with Terraform > Managing Union Resources with Terraform**

Learn about available resources and data sources

### **Managing Union with Terraform > Security Best Practices**

Securely manage API keys and credentials

## Requirements

- Terraform >= 1.0
- Union API key (generated using the [Flyte CLI](https://www.union.ai/docs/v2/union/api-reference/flyte-cli/page.md))
- Access to a Union deployment

=== PAGE: https://www.union.ai/docs/v2/union/deployment/terraform/installation ===

# Installing the Union Terraform Provider

Documentation for installing and configuring the Union Terraform provider is coming soon.

In the meantime, you can find the latest information about the provider in the [Terraform Registry](https://registry.terraform.io/providers/unionai/unionai/latest/docs).

## Quick Start

To use the Union Terraform provider, add it to your Terraform configuration:

```hcl
terraform {
  required_providers {
    unionai = {
      source  = "unionai/unionai"
      version = "~> 1.0"
    }
  }
}

provider "unionai" {
  api_key = var.unionai_api_key
}
```

> **Security Note:** Never hardcode API keys in your Terraform files. See [Security Best Practices](./security) for recommended approaches to securely manage your API keys.

## Versioning

To choose the appropriate version of the provider (likely you should choose latest):

1. Visit the Provider Registry site and observe the latest version number
2. Use that version number in the provider declaration above

For detailed installation instructions, please refer to the [Terraform Registry documentation](https://registry.terraform.io/providers/unionai/unionai/latest/docs).

=== PAGE: https://www.union.ai/docs/v2/union/deployment/terraform/management ===

# 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:

```hcl
terraform {
  required_providers {
    unionai = {
      source  = "unionai/unionai"
      version = "~> 1.0"
    }
  }
}

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):

```hcl
provider "unionai" {
  api_key = var.unionai_api_key
}
```

### 2. Environment Variable

Set the `UNIONAI_API_KEY` environment variable:

```bash
export UNIONAI_API_KEY="your-api-key"
```

### Generating an API Key

Create an API key using the Flyte CLI:

```bash
union create api-key admin --name "terraform-api-key"
```

For more information on creating API keys, see the [Flyte CLI documentation](https://www.union.ai/docs/v2/union/api-reference/flyte-cli).

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:

```hcl
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:

```hcl
resource "unionai_user" "example" {
  email      = "user@example.com"
  first_name = "John"
  last_name  = "Doe"
}
```

### Roles

Define custom roles for access control:

```hcl
resource "unionai_role" "example" {
  name        = "custom-role"
  description = "Custom role with specific permissions"
}
```

### Policies

Create access policies that define permissions:

```hcl
resource "unionai_policy" "example" {
  name        = "project-access-policy"
  description = "Policy for project access"
  # Policy configuration details
}
```

### API Keys

Generate and manage API keys programmatically:

```hcl
resource "unionai_api_key" "example" {
  name        = "automation-key"
  description = "API key for CI/CD automation"
}
```

### OAuth Applications

Configure OAuth applications for external integrations:

```hcl
resource "unionai_oauth_application" "example" {
  name         = "external-app"
  redirect_uri = "https://example.com/callback"
}
```

### Access Assignments

Assign users and applications to resources with specific roles:

```hcl
resource "unionai_user_access" "example" {
  user_id    = unionai_user.example.id
  project_id = unionai_project.example.id
  role_id    = unionai_role.example.id
}

resource "unionai_application_access" "example" {
  application_id = unionai_oauth_application.example.id
  project_id     = unionai_project.example.id
  role_id        = unionai_role.example.id
}
```

## Available Data Sources

Data sources allow you to query existing Union resources for use in your Terraform configuration.

### Projects

Query existing projects:

```hcl
data "unionai_project" "existing" {
  name = "existing-project"
}
```

### Users

Look up user information:

```hcl
data "unionai_user" "existing" {
  email = "user@example.com"
}
```

### Roles

Reference existing roles:

```hcl
data "unionai_role" "admin" {
  name = "admin"
}
```

### Policies

Query existing policies:

```hcl
data "unionai_policy" "existing" {
  name = "default-policy"
}
```

### API Keys

Reference existing API keys:

```hcl
data "unionai_api_key" "existing" {
  name = "existing-key"
}
```

### Applications

Look up OAuth applications:

```hcl
data "unionai_application" "existing" {
  name = "existing-app"
}
```

### Data Plane Information

Query information about the data plane:

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

### Control Plane Information

Access control plane details:

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

### Data Plane Listings

List all available data planes:

```hcl
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:

```hcl
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:

```hcl
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
# .gitignore
*.tfvars
*.tfstate
*.tfstate.backup
.terraform/
```

### Use Remote State

For team environments, use remote state storage:

```hcl
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:

```hcl
terraform {
  required_providers {
    unionai = {
      source  = "unionai/unionai"
      version = "~> 1.0"
    }
  }
}

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"
}

# Create a user
resource "unionai_user" "data_scientist" {
  email      = "data.scientist@example.com"
  first_name = "Jane"
  last_name  = "Smith"
}

# Assign user to project with role
resource "unionai_user_access" "scientist_access" {
  user_id    = unionai_user.data_scientist.id
  project_id = unionai_project.ml_pipeline.id
  role_id    = unionai_role.ml_engineer.id
}

# Create API key for automation
resource "unionai_api_key" "ci_cd" {
  name        = "ci-cd-pipeline"
  description = "API key for CI/CD automation"
}
```

## Additional Resources

- [Union Terraform Provider Documentation](https://registry.terraform.io/providers/unionai/unionai/latest/docs)
- [Terraform Documentation](https://www.terraform.io/docs)
- [Flyte CLI Documentation](https://www.union.ai/docs/v2/union/api-reference/flyte-cli)

## Requirements

- **Terraform**: >= 1.0
- **Union API Key**: Generated via 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](https://registry.terraform.io/providers/unionai/unionai/latest/docs).

=== PAGE: https://www.union.ai/docs/v2/union/deployment/terraform/security ===

# Security Best Practices

**Never hardcode API keys directly in your Terraform configuration files.** API keys are sensitive credentials that should be stored securely and never committed to version control.

## Recommended Approaches

### 1. Use Cloud Secret Managers

Store your Union API key in a cloud-based secret manager and retrieve it dynamically:

#### AWS Secrets Manager

```hcl
data "aws_secretsmanager_secret" "unionai_api_key" {
  name = "unionai/terraform-api-key"
}

data "aws_secretsmanager_secret_version" "unionai_api_key" {
  secret_id = data.aws_secretsmanager_secret.unionai_api_key.id
}

provider "unionai" {
  api_key = data.aws_secretsmanager_secret_version.unionai_api_key.secret_string
}
```

#### Google Cloud Secret Manager

```hcl
data "google_secret_manager_secret_version" "unionai_api_key" {
  secret  = "unionai-terraform-api-key"
  project = "your-project-id"
}

provider "unionai" {
  api_key = data.google_secret_manager_secret_version.unionai_api_key.secret_data
}
```

#### Azure Key Vault

```hcl
data "azurerm_key_vault" "main" {
  name                = "your-keyvault-name"
  resource_group_name = "your-resource-group"
}

data "azurerm_key_vault_secret" "unionai_api_key" {
  name         = "unionai-api-key"
  key_vault_id = data.azurerm_key_vault.main.id
}

provider "unionai" {
  api_key = data.azurerm_key_vault_secret.unionai_api_key.value
}
```

### 2. Use HashiCorp Vault

For multi-cloud or on-premises deployments, HashiCorp Vault provides centralized secret management:

```hcl
data "vault_generic_secret" "unionai_api_key" {
  path = "secret/terraform/unionai"
}

provider "unionai" {
  api_key = data.vault_generic_secret.unionai_api_key.data["api_key"]
}
```

### 3. Use Environment Variables

For local development or CI/CD pipelines, use environment variables:

```bash
export UNIONAI_API_KEY="your-api-key-here"
```

The provider will automatically read from the `UNIONAI_API_KEY` environment variable:

```hcl
provider "unionai" {
  # api_key is read from UNIONAI_API_KEY environment variable
}
```

### 4. Use Terraform Variables with `.tfvars` Files

If using variable files, ensure they are excluded from version control:

```hcl
# variables.tf
variable "unionai_api_key" {
  description = "Union API key"
  type        = string
  sensitive   = true
}

# main.tf
provider "unionai" {
  api_key = var.unionai_api_key
}
```

Create a `terraform.tfvars` file (add to `.gitignore`):

```hcl
unionai_api_key = "your-api-key-here"
```

## Additional Security Measures

### Encrypt Terraform State

Always use encrypted remote state backends to protect sensitive data:

```hcl
terraform {
  backend "s3" {
    bucket         = "my-terraform-state"
    key            = "union/terraform.tfstate"
    region         = "us-west-2"
    encrypt        = true
    dynamodb_table = "terraform-state-lock"
  }
}
```

### Use State Locking

Enable state locking to prevent concurrent modifications:

- **AWS S3**: Use DynamoDB for state locking
- **Google Cloud Storage**: Automatic state locking
- **Azure Blob Storage**: Automatic state locking

### Rotate API Keys Regularly

Implement a rotation schedule for your API keys:

1. Generate a new API key using the Flyte CLI
2. Update the key in your secret manager
3. Verify Terraform can authenticate with the new key
4. Delete the old API key

### Restrict Provider Permissions

Use the `allowed_orgs` parameter to limit which organizations the provider can access:

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

This prevents accidental operations on the wrong organization.

### Use Separate API Keys per Environment

Create different API keys for each environment (development, staging, production):

```hcl
# Development
provider "unionai" {
  alias   = "dev"
  api_key = var.dev_api_key
}

# Production
provider "unionai" {
  alias   = "prod"
  api_key = var.prod_api_key
}
```

## Security Checklist

- ✅ Store API keys in a secret manager or secure vault
- ✅ Use environment variables for local development
- ✅ Mark variables containing secrets as `sensitive = true`
- ✅ Add `*.tfvars`, `*.tfstate`, and `*.tfstate.backup` to `.gitignore`
- ✅ Use remote state backends with encryption enabled
- ✅ Enable state locking to prevent concurrent modifications
- ✅ Rotate API keys regularly
- ✅ Use separate API keys per environment
- ✅ Restrict provider access with `allowed_orgs`
- ✅ Review Terraform plans before applying changes
- ❌ Never commit API keys to version control
- ❌ Never hardcode API keys in `.tf` files
- ❌ Never share API keys in plain text (chat, email, etc.)
- ❌ Never use production API keys in development environments

## CI/CD Pipeline Security

When using Terraform in CI/CD pipelines:

### GitHub Actions

```yaml
name: Terraform

on:
  push:
    branches: [main]

jobs:
  terraform:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Setup Terraform
        uses: hashicorp/setup-terraform@v2

      - name: Terraform Init
        env:
          UNIONAI_API_KEY: ${{ secrets.UNIONAI_API_KEY }}
        run: terraform init

      - name: Terraform Apply
        env:
          UNIONAI_API_KEY: ${{ secrets.UNIONAI_API_KEY }}
        run: terraform apply -auto-approve
```

### GitLab CI

```yaml
terraform:
  image: hashicorp/terraform:latest
  variables:
    UNIONAI_API_KEY: $UNIONAI_API_KEY
  script:
    - terraform init
    - terraform apply -auto-approve
  only:
    - main
```

### Best Practices for CI/CD

- Store API keys as encrypted secrets in your CI/CD platform
- Use separate API keys for CI/CD (not personal keys)
- Implement approval gates for production deployments
- Enable audit logging for all Terraform operations
- Restrict who can view/modify CI/CD secrets

## Additional Resources

- [Terraform Security Best Practices](https://developer.hashicorp.com/terraform/tutorials/configuration-language/sensitive-variables)
- [HashiCorp Vault Documentation](https://developer.hashicorp.com/vault/docs)
- [Flyte CLI Documentation](https://www.union.ai/docs/v2/union/api-reference/flyte-cli)

