Co Provision
Resource co-provisioning
This section contains an example of Resource Definitions using the Terraform Driver and illustrating the co-provisioning concept.
Scenario: For each AWS S3 bucket resource an AWS IAM policy resource must be created. The bucket properties (region, ARN) should be passed to the policy resource. In other words, an IAM Policy resource depends on a S3 resource, but it needs to be created automatically.
Any time a Workload references a S3 resource using this Resource Definition, an IAM Policy resource will be co-provisioned and reference the S3 resource. The resulting Resource Graph will look like this:
flowchart LR
R1(Workload) --->|references| R2(S3)
N1(AWS Policy) --->|references| R2
classDef pClass stroke-width:1px
classDef rClass stroke-width:2px
classDef nClass stroke-width:2px,stroke-dasharray: 5 5
class R1 pClass
class R2 rClass
class N1 nClass
Resource Definitions
aws-policy-co-provision.yaml
(
view on GitHub
)
:
apiVersion: entity.humanitec.io/v1b1
kind: Definition
metadata:
id: aws-policy-co-provision
entity:
name: aws-policy-co-provision
type: aws-policy
driver_type: humanitec/terraform
# Use the credentials injected via the driver_account to set variables as expected by your Terraform code
driver_account: aws
driver_inputs:
values:
variables:
REGION: ${resources.s3.outputs.region}
BUCKET: ${resources.s3.outputs.bucket}
BUCKET_ARN: ${resources.s3.outputs.arn}
credentials_config:
variables:
ACCESS_KEY_ID: AccessKeyId
ACCESS_KEY_VALUE: SecretAccessKey
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
}
# ... Terraform code reduced for brevity
resource "aws_iam_policy" "bucket" {
name = "$\{var.BUCKET}-policy"
policy = data.aws_iam_policy_document.main.json
}
data "aws_iam_policy_document" "main" {
statement {
effect = "Allow"
actions = [
"s3:GetObject",
"s3:ListBucket",
]
resources = [
var.BUCKET_ARN,
]
}
}
s3-co-provision.yaml
(
view on GitHub
)
:
apiVersion: entity.humanitec.io/v1b1
kind: Definition
metadata:
id: s3-co-provision
entity:
name: s3-co-provision
type: s3
driver_type: humanitec/terraform
# Use the credentials injected via the driver_account to set variables as expected by your Terraform code
driver_account: aws
driver_inputs:
values:
variables:
REGION: eu-central-1
credentials_config:
variables:
ACCESS_KEY_ID: AccessKeyId
ACCESS_KEY_VALUE: SecretAccessKey
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
}
# ... Terraform code reduced for brevity
resource "aws_s3_bucket" "bucket" {
bucket = my-bucket
}
output "bucket" {
value = aws_s3_bucket.main.id
}
output "arn" {
value = aws_s3_bucket.main.arn
}
output "region" {
value = aws_s3_bucket.main.region
}
# Co-provision aws-policy resource
provision:
aws-policy:
is_dependent: false
aws-policy-co-provision.tf
(
view on GitHub
)
:
resource "humanitec_resource_definition" "aws-policy-co-provision" {
driver_type = "humanitec/terraform"
id = "aws-policy-co-provision"
name = "aws-policy-co-provision"
type = "aws-policy"
driver_account = "aws"
driver_inputs = {
values_string = jsonencode({
"variables" = {
"REGION" = "$${resources.s3.outputs.region}"
"BUCKET" = "$${resources.s3.outputs.bucket}"
"BUCKET_ARN" = "$${resources.s3.outputs.arn}"
}
"credentials_config" = {
"variables" = {
"ACCESS_KEY_ID" = "AccessKeyId"
"ACCESS_KEY_VALUE" = "SecretAccessKey"
}
}
"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
}
# ... Terraform code reduced for brevity
resource "aws_iam_policy" "bucket" {
name = "$\{var.BUCKET}-policy"
policy = data.aws_iam_policy_document.main.json
}
data "aws_iam_policy_document" "main" {
statement {
effect = "Allow"
actions = [
"s3:GetObject",
"s3:ListBucket",
]
resources = [
var.BUCKET_ARN,
]
}
}
END_OF_TEXT
})
}
}
s3-co-provision.tf
(
view on GitHub
)
:
resource "humanitec_resource_definition" "s3-co-provision" {
driver_type = "humanitec/terraform"
id = "s3-co-provision"
name = "s3-co-provision"
type = "s3"
driver_account = "aws"
driver_inputs = {
values_string = jsonencode({
"variables" = {
"REGION" = "eu-central-1"
}
"credentials_config" = {
"variables" = {
"ACCESS_KEY_ID" = "AccessKeyId"
"ACCESS_KEY_VALUE" = "SecretAccessKey"
}
}
"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
}
# ... Terraform code reduced for brevity
resource "aws_s3_bucket" "bucket" {
bucket = my-bucket
}
output "bucket" {
value = aws_s3_bucket.main.id
}
output "arn" {
value = aws_s3_bucket.main.arn
}
output "region" {
value = aws_s3_bucket.main.region
}
END_OF_TEXT
})
}
provision = {
"aws-policy" = {
is_dependent = false
}
}
}