This guide demonstrates how to use Infisical to manage secrets in your Terraform infrastructure code, supporting both traditional data sources and ephemeral resources for enhanced security. It uses:

Prerequisites

Before you begin, make sure you have:

  • Terraform installed (v1.10.0+ for ephemeral resources)
  • An Infisical account with access to a project
  • Basic understanding of Terraform and infrastructure as code

Project Setup

Configure Provider

First, specify the Infisical provider in your Terraform configuration:

terraform {
  required_providers {
    infisical = {
      source = "infisical/infisical"
    }
  }
}

Authentication

Configure the provider using one of these authentication methods:

Using a Machine Identity, you can authenticate your Terraform provider using either OIDC Auth or Universal Auth methods.

provider "infisical" {
  host          = "https://app.infisical.com" # Optional for cloud, required for self-hosted
  auth {
    universal { # or use oidc authentication method by providing an identity_id
      client_id     = var.infisical_client_id
      client_secret = var.infisical_client_secret
    }
  }
}

Learn more about machine identities.

Service Token (Legacy)

Machine Identity authentication is strongly recommended as the secure and modern method. Service tokens are considered legacy and will be deprecated in a future release.

provider "infisical" {
  host          = "https://app.infisical.com"
  service_token = var.infisical_service_token
}

Using Secrets in Terraform

Infisical provides two methods to fetch and use secrets in your Terraform configurations:

Ephemeral resources, introduced in Terraform v1.10, provide enhanced security by ensuring sensitive values are never persisted in state files. This is the recommended approach for handling secrets in your infrastructure code.

# Fetch database credentials ephemerally
ephemeral "infisical_secret" "db_creds" {
  name         = "DB_CREDENTIALS"
  env_slug     = "prod"
  workspace_id = var.infisical_workspace_id
  folder_path  = "/database"
}

# Use the credentials to configure a provider
provider "postgresql" {
  host     = data.aws_db_instance.example.address
  port     = data.aws_db_instance.example.port
  username = jsondecode(ephemeral.infisical_secret.db_creds.value)["username"]
  password = jsondecode(ephemeral.infisical_secret.db_creds.value)["password"]
}

Key benefits:

  • Values are never stored in state files
  • Secrets are fetched on-demand during each Terraform operation
  • Perfect for GitOps workflows
  • Improved security posture for your infrastructure as code

Method 2: Data Sources

For backwards compatibility or when working with older Terraform versions, you can use the traditional data source approach:

# Fetch all secrets in a folder
data "infisical_secrets" "my_secrets" {
  env_slug     = "dev"
  workspace_id = var.infisical_workspace_id
  folder_path  = "/api"
}

# Use individual secrets
resource "aws_db_instance" "example" {
  username = data.infisical_secrets.my_secrets.secrets["DB_USER"]
  password = data.infisical_secrets.my_secrets.secrets["DB_PASS"]
}

When using data sources, secret values are stored in Terraform’s state file. Ensure your state file is properly secured.

Common Use Cases

Secure Database Credential Management

Manage database credentials securely without exposing sensitive information in your state files:

# Fetch database credentials securely
ephemeral "infisical_secret" "db_creds" {
  name         = "DB_CREDENTIALS"
  env_slug     = "prod"
  workspace_id = var.infisical_workspace_id
  folder_path  = "/database"
}

# Use the credentials in your database instance
resource "aws_db_instance" "example" {
  identifier        = "my-database"
  allocated_storage = 20
  engine            = "postgres"
  engine_version    = "14.0"
  instance_class    = "db.t3.micro"
  
  # Securely inject credentials from Infisical
  username = jsondecode(ephemeral.infisical_secret.db_creds.value)["username"]
  password = jsondecode(ephemeral.infisical_secret.db_creds.value)["password"]
}

GitOps Workflow with OIDC

To eliminate the need for static credentials, you can authenticate your workflow using OpenID Connect (OIDC) through providers like the Infisical Secrets GitHub Action. Once authenticated, you can securely access secrets through the Infisical provider:

provider "infisical" {
  # Auth credentials automatically injected from the environment
}

# Fetch deployment credentials
ephemeral "infisical_secret" "deploy_token" {
  name         = "DEPLOY_TOKEN"
  env_slug     = "prod"
  workspace_id = var.infisical_workspace_id
  folder_path  = "/deployment"
}

For detailed instructions on setting up OIDC authentication with GitHub Actions, refer to our GitHub Actions OIDC guide.

Best Practices

  1. Use Ephemeral Resources: Whenever possible, use ephemeral resources instead of data sources for improved security.

  2. Organize Secrets: Structure your secrets in Infisical using folders to maintain clean separation:

    ephemeral "infisical_secret" "db_secret" {
      folder_path = "/databases/postgresql"  # Organized by service
      # ...
    }
    
  3. Variable Usage: Use Terraform variables for workspace IDs and environment slugs:

    variable "environment" {
      description = "Environment (dev, staging, prod)"
      type        = string
    }
    
    ephemeral "infisical_secret" "secret" {
      env_slug = var.environment
      # ...
    }
    
  4. Error Handling: Add lifecycle blocks for critical secrets:

    ephemeral "infisical_secret" "critical_secret" {
      # ...
      lifecycle {
        postcondition {
          condition     = length(self.value) > 0
          error_message = "Critical secret must not be empty"
        }
      }
    }
    

FAQ

See also: