Back to Infisical

Terraform

docs/integrations/frameworks/terraform.mdx

0.159.258.0 KB
Original Source

{/* 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:

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

Authentication

Configure the provider using one of these authentication methods:

Machine Identity (Recommended)

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

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

<Warning> 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. </Warning>
hcl
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.

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

hcl
# 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"]
}
<Warning> When using data sources, secret values are stored in Terraform's state file. Ensure your state file is properly secured. </Warning>

Common Use Cases

Secure Database Credential Management

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

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

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

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

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

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

FAQ

<AccordionGroup> <Accordion title="What happens if I'm using an older version of Terraform?"> If you're using Terraform < v1.10.0, you'll need to use the data source approach. Consider upgrading to take advantage of the enhanced security features provided by ephemeral resources. </Accordion> <Accordion title="Can I mix ephemeral resources and data sources?"> Yes, you can use both in the same configuration. However, we recommend using ephemeral resources for any sensitive values to ensure they're not stored in state. </Accordion> <Accordion title="How do I secure my state file when using data sources?"> When using data sources, follow Terraform's best practices for state management: - Use remote state with encryption at rest - Implement proper access controls - Consider using state encryption - Treat the state like a secret
    Better yet, use ephemeral resources to avoid storing sensitive values in state entirely.
</Accordion>
</AccordionGroup>

See also: