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: []