Resource Definitions

Driver

Capability

Backends

Backends

Humanitec manages the state file for the local backend. This is the backend that is used if no backend is specified.

In order to manage your own state, you will need to define your own backend. We recommend that the backend configuration is defined in the script part of the Resource Definition - i.e. as an override.tf file (see the Inputs of the Terraform Driver). This allows the backend to be tuned per resource instance.

In order to centralize configuration, it is also recommended to create a config resource that can be used to centrally manage the backend configuration.

In this example, there are two config resources defined. Both are using the Template Driver to generate outputs for use in the example Resource Definition:

  • backend-config.yaml which provides shared backend configuration that can be used across Resource Definitions.
  • account-config-aws.yaml which provides credentials used by the provider.

The example Resource Definition s3-backend.yaml does the following:

  • Configures a backend using the backend-config.yaml.
  • Configures the provider using a different set of credentials from account-config-aws.yaml.
  • Provisions an s3 bucket.

account-config-aws.yaml (view on GitHub) :

apiVersion: entity.humanitec.io/v1b1
kind: Definition
metadata:
  id: account-config-aws
entity:
  criteria:
    # This res_id is used in the resource reference in the s3-backend Resource Definition.
    - res_id: aws-account

  # The driver_account references a Cloud Account configured in the Platform Orchestrator.
  # Replace with the name your AWS Cloud Account.
  driver_account: aws-credentials

  driver_inputs:
    values:
      templates:
        secrets: |
          aws_access_key_id: {{ .driver.secrets.account.aws_access_key_id }}
          aws_secret_access_key: {{ .driver.secrets.account.aws_secret_access_key }}
          credentials_file: |
            [default]
            aws_access_key_id = {{ .driver.secrets.account.aws_access_key_id }}
            aws_secret_access_key = {{ .driver.secrets.account.aws_secret_access_key }}
  driver_type: humanitec/template
  name: account-config-aws
  type: config


backend-config.yaml (view on GitHub) :

apiVersion: entity.humanitec.io/v1b1
kind: Definition
metadata:
  id: tf-backend-config
entity:
  criteria:
    # This res_id is used in the resource reference in the s3-backend Resource Definition.
    - res_id: tf-backend

  # The driver_account references a Cloud Account configured in the Platform Orchestrator.
  # Replace with the name of your AWS Cloud Account.
  driver_account: aws-credentials

  driver_inputs:
    values:
      templates:
        outputs: |
          bucket: my-terraform-state-bucket
          key_prefix:  "tf-state/"
          region: us-east-1
        secrets: |
          credentials_file: |
            [default]
            aws_access_key_id = {{ .driver.secrets.account.aws_access_key_id }}
            aws_secret_access_key = {{ .driver.secrets.account.aws_secret_access_key }}
  driver_type: humanitec/template
  name: tf-backend-config
  type: config


s3-backend.yaml (view on GitHub) :

apiVersion: entity.humanitec.io/v1b1
kind: Definition
metadata:
  id: s3-backend-example
entity:
  driver_inputs:
    # We are using secret references to write the credentials using their "value" element.
    # Using "secrets" instead would work too, but due to the placeholders in the values, the
    # Platform Orchestrator will resolve them to the exact secret references used here
    # in the resulting Resource Definition.
    # This structure therefore represents the way the Platform Orchestrator manages the Resource Definition
    # and is better suited to any round-trip engineering, if needed.
    secret_refs:
      files:
        # Credentials for the AWS provider
        aws_creds:
          # Using the resource ID "#aws-account" to fulfill the matching criteria of the "account-config-aws" config resource.  
          value: ${resources.config#aws-account.outputs.credentials_file}
        
        # In general, the credentials for the backend should be different from those of the provider
        backend_creds:
          # Using the resource ID "#tf-backend" to fulfill the matching criteria of the "tf-backend-config" config resource.
          value: ${resources.config#tf-backend.outputs.credentials_file}
    values:
      script: |-
        variable "region" {}

        terraform {
          backend {
            bucket = "${resources.config#tf-backend.outputs.bucket}"
            key    = "${resources.config#tf-backend.outputs.prefix}${context.app.id}/${context.env.id}/${context.res.type}.${context.res.class}/${context.res.id}"
            region = "${resources.config#tf-backend.outputs.region}"
            shared_credentials_files = ["backend_creds"]
          }

          required_providers {
            aws = {
              source = "hashicorp/aws"
            }
          }
        }

        provider "aws" {
          region     = var.region

          # The file is defined above. The provide will read the creds from this file.
          shared_credentials_files = ["aws_creds"]
        }
        
        output "bucket" {
          value = aws_s3_bucket.bucket.bucket
        }

        output "region" {
          value = var.region
        }

        resource "aws_s3_bucket" "bucket" {
          bucket = "$\{replace("${context.res.id}", "^.*\.", "")}-standard-${context.env.id}-${context.app.id}-${context.org.id}"
          tags = {
            Humanitec = true
          }
        }

      variables:
        region: us-east-1
  driver_type: humanitec/terraform
  name: s3-backend-example
  type: s3

  # Supply matching criteria
  criteria: []
Top