terraform-provider-sops

repository·master·Indexed 20 days ago

https://github.com/carlpett/terraform-provider-sops

A Terraform provider that allows users to decrypt and use files encrypted with SOPS (Secrets Operations) within Terraform configurations. It provides data sources and ephemeral resources—sops_file and sops_external—to handle encrypted content from local files or remote sources. Supports various input types including yaml, json, dotenv, ini, and raw. Ephemeral resources (requiring Terraform v1.11+ and provider v1.3.0+) allow secrets to be used during the apply phase without being persisted in the Terraform state file.

Tokens
5K
Snippets
17
Records
25
Agent score
69%

What's inside terraform-provider-sops

  1. Access nested data in sops_file

    master

    When using sops_file, you can access nested data in two ways:

    1. Via the data map: Use dot-separated strings as keys to reach nested values. For example, if your JSON has a db object with a password field, access it using data["db.password"].
    2. Via the raw string: Use Terraform's jsondecode() function on the raw attribute to convert the decrypted content into a Terraform object, then use standard object notation (e.g., jsondecode(data.sops_file.name.raw).db.password).
    output "mapped_nested_value" {
      value = data.sops_file.demo_secret.data["db.password"]
    }
    
    output "nested_json_value" {
      value = jsondecode(data.sops_file.demo_secret.raw).db.password
    }
  2. Use the sops_external ephemeral resource

    master

    The sops_external ephemeral resource allows you to read and decrypt data from a SOPS-encrypted string that is not stored in a local file. This is particularly useful when encrypted data is fetched from a remote source (like an HTTP endpoint) or provided via another resource's output.

    To use it, provide the encrypted string to the source argument and specify the format of the underlying unencrypted data using input_type.

    data "http" "remote_sops_data" {
      url = "https://sops.example/my-data"
    }
    
    ephemeral "sops_external" "demo_secret" {
      source     = data.http.remote_sops_data.body
      input_type = "yaml"
    }
    
    output "root_value_hello" {
      value = ephemeral.sops_external.demo_secret.data.hello
    }
  3. Configure SOPS for CI usage

    master
    When running Terraform in a CI/CD environment, you must ensure that the same environment variables or context (e.g., AWS credentials, GCP credentials, PGP keys) used by SOPS locally are available to the CI runtime. The provider does not manage these credentials; it relies on the environment to provide them.
  4. Migrate to the required_providers block (Terraform 0.13+)

    master

    If you are upgrading from an older version of the SOPS provider that used legacy data source blocks, you must replace the old provider in your state to avoid errors.

    Run the following command to transition from the legacy provider to the registry-based provider:

    terraform state replace-provider registry.terraform.io/-/sops registry.terraform.io/carlpett/sops

    terraform state replace-provider registry.terraform.io/-/sops registry.terraform.io/carlpett/sops
  5. Migrate existing states to the new provider registry

    master

    If you are migrating a state from Terraform 0.12 or older, you must update how the provider is referenced in your state file. Use the terraform state replace-provider command to transition from the legacy registry to the current one.

    terraform state replace-provider registry.terraform.io/-/sops registry.terraform.io/carlpett/sops
  6. Use the sops_file data source to read encrypted files

    master

    The sops_file data source allows you to read and unmarshal data from a SOPS-encrypted file on disk. You must provide the path to the encrypted file via source_file. The provider automatically detects the file format based on the extension, but you can explicitly set input_type if your file uses a non-standard extension.

    To access the decrypted content, you can use the data attribute (a map of strings) or the raw attribute (the entire unencrypted file as a string).

    provider "sops" {}
    
    data "sops_file" "demo-secret" {
      source_file = "demo-secret.enc.json"
    }
    
    output "root-value-password" {
      # Access the password variable from the map
      value = data.sops_file.demo-secret.data["password"]
    }
    
    output "mapped-nested-value" {
      # Access the password variable that is under db via the terraform map of data
      value = data.sops_file.demo-secret.data["db.password"]
    }
    
    output "nested-json-value" {
      # Access the password variable that is under db via the terraform object
      value = jsondecode(data.sops_file.demo-secret.raw).db.password
    }
  7. Use the SOPS Provider to read encrypted files

    master

    The sops provider allows you to use files encrypted with SOPS within your Terraform configuration.

    Security Warning: To prevent plaintext secrets from being written to disk, you must use a secure remote state backend. Refer to the official Terraform documentation on Sensitive Data in State for guidance.

    To use the provider, declare the sops provider and use the sops_file data source to load an encrypted file.

    provider "sops" {}
    
    data "sops_file" "demo_secret" {
      source_file = "demo-secret.enc.json"
    }
  8. Use the sops_file ephemeral resource to decrypt files

    master

    The sops_file ephemeral resource allows you to decrypt SOPS-encrypted files and access their contents within your Terraform configuration. Because it is an ephemeral resource, the decrypted data is available during the plan/apply phase but is not stored in the Terraform state file as a persistent resource.

    To use it, define the source_file path. You can then access the decrypted content via the data map (using dot-notation for nested keys) or the raw string.

    provider "sops" {}
    
    ephemeral "sops_file" "demo_secret" {
      source_file = "demo_secret.enc.json"
    }
    
    output "root_value_password" {
      # Access the password variable from the map
      value = data.sops_file.demo_secret.data["password"]
    }
    
    output "mapped_nested_value" {
      # Access the password variable that is under db via the terraform map of data
      value = data.sops_file.demo_secret.data["db.password"]
    }
    
    output "nested_json_value" {
      # Access the password variable that is under db via the terraform object
      value = jsondecode(data.sops_file.demo_secret.raw).db.password
    }
  9. Locate provider and data source examples

    master

    The repository contains example Terraform files used for documentation and manual testing. If you are looking for specific implementation patterns, look in the following directory structures:

    • Provider examples: Located in provider/provider.tf.
    • Data source examples: Located in data-sources/[full-data-source-name]/data-source.tf.
    • Resource examples: Located in resources/[full-resource-name]/resource.tf.
  10. Use the sops_external data source to read remote encrypted data

    master

    The sops_external data source allows you to decrypt SOPS-encrypted strings that are not stored in local files. This is particularly useful when your encrypted data is fetched from a remote URL or provided via another data source.

    To use it, provide the encrypted string to the source argument and specify the format of the unencrypted content using input_type (e.g., yaml, json, dotenv, ini, or raw). The decrypted content is then accessible via the data map.

    data "http" "remote_sops_data" {
      url = "https://sops.example/my-data"
    }
    
    data "sops_external" "demo_secret" {
      source     = data.http.remote_sops_data.body
      input_type = "yaml"
    }
    
    output "root-value-hello" {
      value = data.sops_external.demo_secret.data.hello
    }