S3
Example: s3 resource based on AWS S3
Configuration
This example configures a s3 Resource Definition using AWS S3, with two different access policies:
basic-admin(full access)basic-read-only(read-only access)
Those Resource Definitions can be used in your Score file using:
resources:
  ...
  s3:
    type: s3
    class: basic-admin
Infrastructure setup
The workload service account will be automatically assigned to the necessary AWS IAM Role with the selected IAM Policy.
graph TD;
  s3["Amazon S3 bucket"]
  policy["Amazon IAM Policy"]
  role["Amazon IAM Role"]
  subgraph EKS Cluster
    pod[workload pod]
    service[Service Account]
  end
  policy --> s3
  policy --> role --> service --> pod
  s3 --> pod
Orchestrator setup
The Resource Graph is using delegator resources to expose shared resources with different access policies.
graph LR;
  workload_1 --> delegator_1["delegator_1, resource_type: s3", class: basic-read-only] --> shared.s3_1["shared.s3_1, resource_type: s3"]
  workload_2 --> delegator_2["delegator_2, resource_type: s3, class: basic-admin"] --> shared.s3_1
  workload_2 --> shared.delegator_1["shared.delegator_1, resource_type: s3, class: basic-read-only"]
  workload_3 --> shared.delegator_1 --> shared.s3_2["shared.s3_2, resource_type: s3"]
Terraform docs
Requirements
| Name | Version | 
|---|---|
| terraform | >= 1.3.0 | 
| aws | ~> 5.0 | 
| humanitec | ~> 1.0 | 
| random | ~> 3.5 | 
Providers
| Name | Version | 
|---|---|
| aws | ~> 5.0 | 
| humanitec | ~> 1.0 | 
| random | ~> 3.5 | 
Modules
| Name | Source | Version | 
|---|---|---|
| iam_policy_s3_admin | ../../humanitec-resource-defs/iam-policy/s3 | n/a | 
| iam_policy_s3_read_only | ../../humanitec-resource-defs/iam-policy/s3 | n/a | 
| iam_role_service_account | ../../humanitec-resource-defs/iam-role/service-account | n/a | 
| k8s_service_account | ../../humanitec-resource-defs/k8s/service-account | n/a | 
| s3_basic | ../../humanitec-resource-defs/s3/basic | n/a | 
| s3_basic_admin | ../../humanitec-resource-defs/s3/delegator | n/a | 
| s3_basic_read_only | ../../humanitec-resource-defs/s3/delegator | n/a | 
| workload | ../../humanitec-resource-defs/workload/service-account | n/a | 
Resources
Inputs
| Name | Description | Type | Default | Required | 
|---|---|---|---|---|
| cluster_name | Name of the EKS cluster | string | 
          n/a | yes | 
| region | AWS Region | string | 
          n/a | yes | 
| name | Name of the example application | string | 
          "hum-rp-s3-example" | 
          no | 
| prefix | Prefix of the created resources | string | 
          "hum-rp-s3-ex-" | 
          no | 
| resource_packs_aws_rev | AWS Resource Pack git branch | string | 
          "refs/heads/main" | 
          no | 
| resource_packs_aws_url | AWS Resource Pack git url | string | 
          "https://github.com/humanitec-architecture/resource-packs-aws.git" | 
          no | 
main.tf
(view on GitHub )
:
# AWS IAM role used by Humanitec to provision resources
locals {
  admin_policy_arn   = "arn:aws:iam::aws:policy/AdministratorAccess"
  humanitec_user_arn = "arn:aws:iam::767398028804:user/humanitec"
}
resource "random_password" "external_id" {
  length  = 16
  special = false
}
data "aws_iam_policy_document" "instance_assume_role_policy" {
  statement {
    actions = ["sts:AssumeRole"]
    principals {
      type        = "AWS"
      identifiers = [local.humanitec_user_arn]
    }
    condition {
      test     = "StringEquals"
      variable = "sts:ExternalId"
      values   = [random_password.external_id.result]
    }
  }
}
resource "aws_iam_role" "humanitec_provisioner" {
  name = var.name
  assume_role_policy = data.aws_iam_policy_document.instance_assume_role_policy.json
}
resource "aws_iam_role_policy_attachment" "humanitec_provisioner" {
  role       = aws_iam_role.humanitec_provisioner.name
  policy_arn = local.admin_policy_arn
}
resource "humanitec_resource_account" "humanitec_provisioner" {
  id   = var.name
  name = var.name
  type = "aws-role"
  credentials = jsonencode({
    aws_role    = aws_iam_role.humanitec_provisioner.arn
    external_id = random_password.external_id.result
  })
  depends_on = [
    # Otherwise the account looses permissions before the resources are deleted
    aws_iam_role_policy_attachment.humanitec_provisioner
  ]
}
# Example application and resource definition criteria
resource "humanitec_application" "example" {
  id   = var.name
  name = var.name
}
# S3 bucket
locals {
  # Classes used to build the resource definition graph
  s3_basic_class            = "basic"
  s3_admin_policy_class     = "s3-basic-admin"
  s3_read_only_policy_class = "s3-basic-read-only"
  # Classes that developers can select from
  s3_basic_admin_class     = "basic-admin"
  s3_basic_read_only_class = "basic-read-only"
}
# Define s3 bucket basic "flavour" as base
module "s3_basic" {
  source = "github.com/humanitec-architecture/resource-packs-aws?ref=v2024-06-14//humanitec-resource-defs/s3/basic"
  resource_packs_aws_url = var.resource_packs_aws_url
  resource_packs_aws_rev = var.resource_packs_aws_rev
  append_logs_to_error   = true
  driver_account         = humanitec_resource_account.humanitec_provisioner.id
  region = var.region
  prefix = var.prefix
}
resource "humanitec_resource_definition_criteria" "s3_basic" {
  resource_definition_id = module.s3_basic.id
  app_id                 = humanitec_application.example.id
  class                  = local.s3_basic_class
  force_delete = true
}
# Add different access policy to s3 basic bucket
# Admin
## Policy
module "iam_policy_s3_admin" {
  source = "github.com/humanitec-architecture/resource-packs-aws?ref=v2024-06-14//humanitec-resource-defs/iam-policy/s3"
  resource_packs_aws_url = var.resource_packs_aws_url
  resource_packs_aws_rev = var.resource_packs_aws_rev
  append_logs_to_error   = true
  driver_account         = humanitec_resource_account.humanitec_provisioner.id
  region = var.region
  policy = "admin"
  prefix = var.prefix
  s3_resource_class = local.s3_basic_class
}
resource "humanitec_resource_definition_criteria" "iam_policy_s3_admin" {
  resource_definition_id = module.iam_policy_s3_admin.id
  app_id                 = humanitec_application.example.id
  class                  = local.s3_admin_policy_class
  force_delete = true
}
## Exposed delegator resource definition
module "s3_basic_admin" {
  source = "github.com/humanitec-architecture/resource-packs-aws?ref=v2024-06-14//humanitec-resource-defs/s3/delegator"
  prefix = var.prefix
  s3_resource_class     = local.s3_basic_class
  policy_resource_class = local.s3_admin_policy_class
}
resource "humanitec_resource_definition_criteria" "s3_basic_admin" {
  resource_definition_id = module.s3_basic_admin.id
  app_id                 = humanitec_application.example.id
  class                  = local.s3_basic_admin_class
  force_delete = true
}
# Read-only
## Policy
module "iam_policy_s3_read_only" {
  source = "github.com/humanitec-architecture/resource-packs-aws?ref=v2024-06-14//humanitec-resource-defs/iam-policy/s3"
  resource_packs_aws_url = var.resource_packs_aws_url
  resource_packs_aws_rev = var.resource_packs_aws_rev
  append_logs_to_error   = true
  driver_account         = humanitec_resource_account.humanitec_provisioner.id
  region = var.region
  policy = "read-only"
  prefix = var.prefix
  s3_resource_class = local.s3_basic_class
}
resource "humanitec_resource_definition_criteria" "iam_policy_s3_read_only" {
  resource_definition_id = module.iam_policy_s3_read_only.id
  app_id                 = humanitec_application.example.id
  class                  = local.s3_read_only_policy_class
  force_delete = true
}
## Exposed delegator resource definition
module "s3_basic_read_only" {
  source = "github.com/humanitec-architecture/resource-packs-aws?ref=v2024-06-14//humanitec-resource-defs/s3/delegator"
  prefix = var.prefix
  s3_resource_class     = local.s3_basic_class
  policy_resource_class = local.s3_read_only_policy_class
}
resource "humanitec_resource_definition_criteria" "s3_basic_read_only" {
  resource_definition_id = module.s3_basic_read_only.id
  app_id                 = humanitec_application.example.id
  class                  = local.s3_basic_read_only_class
  force_delete = true
}
# Required resources for workload identity
module "k8s_service_account" {
  source = "github.com/humanitec-architecture/resource-packs-aws?ref=v2024-06-14//humanitec-resource-defs/k8s/service-account"
  prefix = var.prefix
}
resource "humanitec_resource_definition_criteria" "k8s_service_account" {
  resource_definition_id = module.k8s_service_account.id
  app_id                 = humanitec_application.example.id
  force_delete = true
}
module "iam_role_service_account" {
  source = "github.com/humanitec-architecture/resource-packs-aws?ref=v2024-06-14//humanitec-resource-defs/iam-role/service-account"
  resource_packs_aws_url = var.resource_packs_aws_url
  resource_packs_aws_rev = var.resource_packs_aws_rev
  append_logs_to_error   = true
  driver_account         = humanitec_resource_account.humanitec_provisioner.id
  region = var.region
  cluster_name = var.cluster_name
  prefix       = var.prefix
}
resource "humanitec_resource_definition_criteria" "iam_role_service_account" {
  resource_definition_id = module.iam_role_service_account.id
  app_id                 = humanitec_application.example.id
  force_delete = true
}
module "workload" {
  source = "github.com/humanitec-architecture/resource-packs-aws?ref=v2024-06-14//humanitec-resource-defs/workload/service-account"
  prefix = var.prefix
}
resource "humanitec_resource_definition_criteria" "workload" {
  resource_definition_id = module.workload.id
  app_id                 = humanitec_application.example.id
  force_delete = true
}
providers.tf
(view on GitHub )
:
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
    humanitec = {
      source  = "humanitec/humanitec"
      version = "~> 1.0"
    }
    random = {
      source  = "hashicorp/random"
      version = "~> 3.5"
    }
  }
  required_version = ">= 1.3.0"
}
provider "aws" {
  default_tags {
    tags = {
      "managed_by" = "terraform"
      "source"     = "github.com/humanitec-architecture/resource-pack-aws"
    }
  }
}
provider "humanitec" {}
provider "random" {}
terraform.tfvars.example
(view on GitHub )
:
# Name of the EKS cluster
cluster_name = ""
# Name of the example application
name = "hum-rp-s3-example"
# Prefix of the created resources
prefix = "hum-rp-s3-ex-"
# AWS Region
region = ""
# AWS Resource Pack git branch
resource_packs_aws_rev = "refs/tags/v2024-06-14"
# AWS Resource Pack git url
resource_packs_aws_url = "https://github.com/humanitec-architecture/resource-packs-aws.git"
variables.tf
(view on GitHub )
:
variable "region" {
  description = "AWS Region"
  type        = string
}
variable "cluster_name" {
  description = "Name of the EKS cluster"
  type        = string
}
variable "resource_packs_aws_url" {
  description = "AWS Resource Pack git url"
  type        = string
  default     = "https://github.com/humanitec-architecture/resource-packs-aws.git"
}
variable "resource_packs_aws_rev" {
  description = "AWS Resource Pack git branch"
  type        = string
  default     = "refs/tags/v2024-06-14"
}
variable "name" {
  description = "Name of the example application"
  type        = string
  default     = "hum-rp-s3-example"
}
variable "prefix" {
  description = "Prefix of the created resources"
  type        = string
  default     = "hum-rp-s3-ex-"
}