Resource Definitions

Driver

Capability

Credentials

Credentials

Different Terraform providers have different ways of being configured. Generally, there are 3 ways that providers can be configured:

  • Directly using parameters on the provider. We call this “provider” credentials.
  • Using a credentials file. The filename is supplied to the provider. We call this “file” credentials.
  • Via environment variables that the provider reads. We call this “environment” credentials.

A powerful approach for working with different cloud accounts for the same resource definition is to reference the credentials from a config resource. By using matching criteria on the config resource, it is possible to specialize the account used in the terraform to different contexts. For example, there might be different AWS Accounts for test and production environments. The same resource definition can be used to manage the terraform and 2 config resources can be created matching to the staging and production environments respectively.

In this set of examples, we provide two config Resource Definitions for AWS and GCP.

AWS

  • Account config (account-config-aws.yaml)
  • Provider Credentials (aws-provider-credentials.yaml)
  • Environment Credentials (aws-environment-credentials.yaml)

GCP

  • Account config (account-config-gcp.yaml)
  • File Credentials (gcp-file-credentials.yaml)

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:
      region: us-east-1

  driver_type: humanitec/echo
  name: account-config-aws
  type: config


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

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

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

  driver_inputs:
    values:
      location: US
      project_id: my-gcp-prject
  driver_type: humanitec/echo
  name: account-config-gcp
  type: config


aws-environment-credentials.yaml (view on GitHub) :

apiVersion: entity.humanitec.io/v1b1
kind: Definition
metadata:
  id: aws-environment-credentials
entity:
  # Use the same account as the config we're ma
  driver_account: ${resources['config.default#aws-account'].account}
  driver_inputs:
    values:
      credentials_config:
        environment:
          AWS_ACCESS_KEY_ID: "AccessKeyId"
          AWS_SECRET_ACCESS_KEY: "SecretAccessKey"
          AWS_SESSION_TOKEN: "SessionToken"
      script: |-

        variable "region" {}

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

        provider "aws" {
          region = var.region
        }

        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: ${resources['config.default#aws-account'].outputs.region}
  driver_type: humanitec/terraform
  name: aws-environment-credentials
  type: s3

  # Supply matching criteria
  criteria: []

aws-provider-credentials.yaml (view on GitHub) :

apiVersion: entity.humanitec.io/v1b1
kind: Definition
metadata:
  id: aws-provider-credentials
entity:
  # Use the same account as the config we're ma
  driver_account: ${resources['config.default#aws-account'].account}
  driver_inputs:
    values:
      credentials_config:
        variables:
          access_key_id: "AccessKeyId"
          secret_access_key: "SecretAccessKey"
          session_token: "SessionToken"
      script: |-

        variable "access_key_id" {
          sensitive = true
        }
        variable "secret_access_key" {
          sensitive = true
        }
        variable "session_token" {
          sensitive = true
        }
        variable "region" {}

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

        provider "aws" {
          region     = var.region
          access_key = var.access_key_id
          secret_key = var.secret_access_key
          token      = var.session_token
        }

        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: ${resources['config.default#aws-account'].outputs.region}
  driver_type: humanitec/terraform
  name: aws-provider-credentials
  type: s3

  # Supply matching criteria
  criteria: []

gcp-file-credentials.yaml (view on GitHub) :

apiVersion: entity.humanitec.io/v1b1
kind: Definition
metadata:
  id: gcp-file-credentials
entity:
  driver_account: ${resources['config.default#gcp-account'].account}
  driver_inputs:
    values:
      credentials_config:
        file: credentials.json
      script: |-

        variable "project_id" {}
        variable "location" {}

        terraform {
          required_providers {
            google = {
              source = "hashicorp/google"
            }
          }
        }
        provider "google" {
          project     = var.project_id

          # The file is defined above. The provider will read a service account token from this file.
          credentials = "credentials.json"
        }
        
        output "name" {
          value = google_storage_bucket.bucket.name
        }

        resource "google_storage_bucket" "bucket" {
          name          = "$\{replace("${context.res.id}", "/^.*\\./", "")}-standard-${context.env.id}-${context.app.id}-${context.org.id}"
          location      = var.location
          force_destroy = true
        }

      variables:
        location: ${resources.config#gcp-account.outputs.location}
        project_id: ${resources.config#gcp-account.outputs.project_id}

  driver_type: humanitec/terraform
  name: gcp-file-credentials
  type: gcs

  # Supply matching criteria
  criteria: []
Top