Resource Definitions

Driver

Capability

Flavor

Resource Type

Credentials

Credentials

General credentials configuration

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)

Temporary credentials

Using a Cloud Account type that supports temporary credentials, those credentials can be easily injected into a Resource Definition using the Terraform Driver. Use a driver_account referencing the Cloud Account in the Resource Definition, and access its the credentials through the supplied values as shown in the examples.

AWS

  • S3 bucket (s3-temporary-credentials.yaml)

GCP

  • Cloud Storage bucket (gcs-temporary-credentials.yaml)

Azure

  • Blob Storage container (azure-blob-storage-temporary-credentials.yaml)

Resource Definitions


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 account provided by the config resource
  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 account provided by the config resource
  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: []

azure-blob-storage-temporary-credentials.yaml ( view on GitHub ) :

# Create Azure Blob Storage container using temporary credentials defined via a Cloud Account
apiVersion: entity.humanitec.io/v1b1
kind: Definition
metadata:
  id: blob-storage-temporary-credentials
entity:
  name: blob-storage-temporary-credentials
  type: azure-blob
  driver_type: humanitec/terraform
  # The driver_account references a Cloud Account of type "azure-identity"
  # which needs to be configured for your Organization.
  driver_account: azure-temporary-creds
  driver_inputs:
    values:
      variables:
        location: eastus
        resource_group_name: my-test-resources
        tenant_id: 3987ae5f-008f-4265-a6ee-e9dcedce4742
        subscription_id: 742f6d8b-1b7b-4c6a-9f37-90bdd5aeb996
        # Managed Identity Client ID used in the Cloud Account
        client_id: c977c44d-3003-464c-b163-03920d4a390b

      # Use the credentials injected via the driver_account
      # to set `oidc_token` variable as expected by your Terraform code
      credentials_config:
        variables:
          oidc_token: oidc_token
      script: |
        # This provider block is using the Terraform variables
        # set through the credentials_config.
        # Variable declarations omitted for brevity.
        provider "azurerm" {
          features {}        
          subscription_id = var.subscription_id
          tenant_id       = var.tenant_id
          client_id       = var.client_id
          use_oidc        = true
          oidc_token      = var.oidc_token
        }

        # ... Terraform code reduced for brevity

        resource "azurerm_storage_account" "example" {
          name                     = "mystorageaccount"
          resource_group_name      = var.resource_group_name
          location                 = var.location
          account_tier             = "Standard"
          account_replication_type = "LRS"
        }
        
        resource "azurerm_storage_container" "example" {
          name                  = "mystorage"
          storage_account_name  = azurerm_storage_account.example.name
          container_access_type = "private"
        }


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

gcs-temporary-credentials.yaml ( view on GitHub ) :

# Create Google Cloud Storage bucket using temporary credentials defined via a Cloud Account
apiVersion: entity.humanitec.io/v1b1
kind: Definition
metadata:
  id: gcs-temporary-credentials
entity:
  name: gcs-temporary-credentials
  type: gcs
  driver_type: humanitec/terraform
  # The driver_account references a Cloud Account of type "gcp-identity"
  # which needs to be configured for your Organization.
  driver_account: gcp-temporary-creds
  driver_inputs:
    values:
      variables:
        location: europe-west3
        project_id: my-gcp-project
      # Use the credentials injected via the driver_account
      # to set variables as expected by your Terraform code
      credentials_config:
        variables:
          access_token: access_token
      script: |
        # This provider block is using the Terraform variables
        # set through the credentials_config.
        # Variable declarations omitted for brevity.
        provider "google" {
          project     = var.project_id
          access_token = var.access_token
        }

        # ... Terraform code reduced for brevity

        resource "google_storage_bucket" "bucket" {
          name          = my-bucket
          location      = var.location
        }


s3-temporary-credentials.yaml ( view on GitHub ) :

# Create S3 bucket using temporary credentials defined via a Cloud Account
apiVersion: entity.humanitec.io/v1b1
kind: Definition
metadata:
  id: s3-temporary-credentials
entity:
  name: s3-temporary-credentials
  type: s3
  driver_type: humanitec/terraform
  # The driver_account references a Cloud Account of type "aws-role"
  # which needs to be configured for your Organization.
  driver_account: aws-temp-creds
  driver_inputs:
    values:
      variables:
        REGION: eu-central-1
      # Use the credentials injected via the driver_account
      # to set variables as expected by your Terraform code
      credentials_config:
        variables:
          ACCESS_KEY_ID: AccessKeyId
          ACCESS_KEY_VALUE: SecretAccessKey
          SESSION_TOKEN: SessionToken
      script: |
        # This provider block is using the Terraform variables
        # set through the credentials_config.
        # Variable declarations omitted for brevity.
        provider "aws" {
          region     = var.REGION
          access_key = var.ACCESS_KEY_ID
          secret_key = var.ACCESS_KEY_VALUE
          token      = var.SESSION_TOKEN
        }

        # ... Terraform code reduced for brevity

        resource "aws_s3_bucket" "bucket" {
          bucket = my-bucket
        }


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

resource "humanitec_resource_definition" "account-config-aws" {
  driver_type    = "humanitec/echo"
  id             = "account-config-aws"
  name           = "account-config-aws"
  type           = "config"
  driver_account = "aws-credentials"
  driver_inputs = {
    values_string = jsonencode({
      "region" = "us-east-1"
    })
  }
}

resource "humanitec_resource_definition_criteria" "account-config-aws_criteria_0" {
  resource_definition_id = resource.humanitec_resource_definition.account-config-aws.id
  res_id                 = "aws-account"
}


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

resource "humanitec_resource_definition" "account-config-gcp" {
  driver_type    = "humanitec/echo"
  id             = "account-config-gcp"
  name           = "account-config-gcp"
  type           = "config"
  driver_account = "gcp-credentials"
  driver_inputs = {
    values_string = jsonencode({
      "location"   = "US"
      "project_id" = "my-gcp-prject"
    })
  }
}

resource "humanitec_resource_definition_criteria" "account-config-gcp_criteria_0" {
  resource_definition_id = resource.humanitec_resource_definition.account-config-gcp.id
  res_id                 = "gcp-account"
}


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

resource "humanitec_resource_definition" "aws-environment-credentials" {
  driver_type    = "humanitec/terraform"
  id             = "aws-environment-credentials"
  name           = "aws-environment-credentials"
  type           = "s3"
  driver_account = "$${resources['config.default#aws-account'].account}"
  driver_inputs = {
    values_string = jsonencode({
      "credentials_config" = {
        "environment" = {
          "AWS_ACCESS_KEY_ID"     = "AccessKeyId"
          "AWS_SECRET_ACCESS_KEY" = "SecretAccessKey"
          "AWS_SESSION_TOKEN"     = "SessionToken"
        }
      }
      "script" = <<END_OF_TEXT

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
  }
}
END_OF_TEXT
      "variables" = {
        "region" = "$${resources['config.default#aws-account'].outputs.region}"
      }
    })
  }
}




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

resource "humanitec_resource_definition" "aws-provider-credentials" {
  driver_type    = "humanitec/terraform"
  id             = "aws-provider-credentials"
  name           = "aws-provider-credentials"
  type           = "s3"
  driver_account = "$${resources['config.default#aws-account'].account}"
  driver_inputs = {
    values_string = jsonencode({
      "credentials_config" = {
        "variables" = {
          "access_key_id"     = "AccessKeyId"
          "secret_access_key" = "SecretAccessKey"
          "session_token"     = "SessionToken"
        }
      }
      "script" = <<END_OF_TEXT

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
  }
}
END_OF_TEXT
      "variables" = {
        "region" = "$${resources['config.default#aws-account'].outputs.region}"
      }
    })
  }
}




azure-blob-storage-temporary-credentials.tf ( view on GitHub ) :

resource "humanitec_resource_definition" "blob-storage-temporary-credentials" {
  driver_type    = "humanitec/terraform"
  id             = "blob-storage-temporary-credentials"
  name           = "blob-storage-temporary-credentials"
  type           = "azure-blob"
  driver_account = "azure-temporary-creds"
  driver_inputs = {
    values_string = jsonencode({
      "variables" = {
        "location"            = "eastus"
        "resource_group_name" = "my-test-resources"
        "tenant_id"           = "3987ae5f-008f-4265-a6ee-e9dcedce4742"
        "subscription_id"     = "742f6d8b-1b7b-4c6a-9f37-90bdd5aeb996"
        "client_id"           = "c977c44d-3003-464c-b163-03920d4a390b"
      }
      "credentials_config" = {
        "variables" = {
          "oidc_token" = "oidc_token"
        }
      }
      "script" = <<END_OF_TEXT
# This provider block is using the Terraform variables
# set through the credentials_config.
# Variable declarations omitted for brevity.
provider "azurerm" {
  features {}        
  subscription_id = var.subscription_id
  tenant_id       = var.tenant_id
  client_id       = var.client_id
  use_oidc        = true
  oidc_token      = var.oidc_token
}

# ... Terraform code reduced for brevity

resource "azurerm_storage_account" "example" {
  name                     = "mystorageaccount"
  resource_group_name      = var.resource_group_name
  location                 = var.location
  account_tier             = "Standard"
  account_replication_type = "LRS"
}

resource "azurerm_storage_container" "example" {
  name                  = "mystorage"
  storage_account_name  = azurerm_storage_account.example.name
  container_access_type = "private"
}
END_OF_TEXT
    })
  }
}



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

resource "humanitec_resource_definition" "gcp-file-credentials" {
  driver_type    = "humanitec/terraform"
  id             = "gcp-file-credentials"
  name           = "gcp-file-credentials"
  type           = "gcs"
  driver_account = "$${resources['config.default#gcp-account'].account}"
  driver_inputs = {
    values_string = jsonencode({
      "credentials_config" = {
        "file" = "credentials.json"
      }
      "script" = <<END_OF_TEXT

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
}
END_OF_TEXT
      "variables" = {
        "location"   = "$${resources.config#gcp-account.outputs.location}"
        "project_id" = "$${resources.config#gcp-account.outputs.project_id}"
      }
    })
  }
}




gcs-temporary-credentials.tf ( view on GitHub ) :

resource "humanitec_resource_definition" "gcs-temporary-credentials" {
  driver_type    = "humanitec/terraform"
  id             = "gcs-temporary-credentials"
  name           = "gcs-temporary-credentials"
  type           = "gcs"
  driver_account = "gcp-temporary-creds"
  driver_inputs = {
    values_string = jsonencode({
      "variables" = {
        "location"   = "europe-west3"
        "project_id" = "my-gcp-project"
      }
      "credentials_config" = {
        "variables" = {
          "access_token" = "access_token"
        }
      }
      "script" = <<END_OF_TEXT
# This provider block is using the Terraform variables
# set through the credentials_config.
# Variable declarations omitted for brevity.
provider "google" {
  project     = var.project_id
  access_token = var.access_token
}

# ... Terraform code reduced for brevity

resource "google_storage_bucket" "bucket" {
  name          = my-bucket
  location      = var.location
}
END_OF_TEXT
    })
  }
}



s3-temporary-credentials.tf ( view on GitHub ) :

resource "humanitec_resource_definition" "s3-temporary-credentials" {
  driver_type    = "humanitec/terraform"
  id             = "s3-temporary-credentials"
  name           = "s3-temporary-credentials"
  type           = "s3"
  driver_account = "aws-temp-creds"
  driver_inputs = {
    values_string = jsonencode({
      "variables" = {
        "REGION" = "eu-central-1"
      }
      "credentials_config" = {
        "variables" = {
          "ACCESS_KEY_ID"    = "AccessKeyId"
          "ACCESS_KEY_VALUE" = "SecretAccessKey"
          "SESSION_TOKEN"    = "SessionToken"
        }
      }
      "script" = <<END_OF_TEXT
# This provider block is using the Terraform variables
# set through the credentials_config.
# Variable declarations omitted for brevity.
provider "aws" {
  region     = var.REGION
  access_key = var.ACCESS_KEY_ID
  secret_key = var.ACCESS_KEY_VALUE
  token      = var.SESSION_TOKEN
}

# ... Terraform code reduced for brevity

resource "aws_s3_bucket" "bucket" {
  bucket = my-bucket
}
END_OF_TEXT
    })
  }
}


Top