Config
Example: config resource the configures ECR image pull secrets
Configuration
This example configures a
config
Resource Definition, which injects an
imagePullSecret
into workloads. An imagePullSecret
is required when the k8s cluster runs outside AWS and workload use private ECR images.
The image used to fetch and periodically renew the secrets can be found here https://github.com/humanitec-architecture/aws-ecr-credentials-refresh and the configs are heavily inspired by https://skryvets.com/blog/2021/03/15/kubernetes-pull-image-from-private-ecr-registry/ .
Orchestrator setup
graph LR;
workload_1 --> config["imagepullsecret, resource_type: config"]
workload_2 --> config["imagepullsecret, resource_type: config"]
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 |
Modules
Name | Source | Version |
---|---|---|
imagepullsecret | ../../../humanitec-resource-defs/config/imagepullsecret | n/a |
Resources
Name | Type |
---|---|
aws_iam_access_key.cluster_ecr_pull | resource |
aws_iam_user.cluster_ecr_pull | resource |
aws_iam_user_policy_attachment.cluster_ecr_pull | resource |
aws_secretsmanager_secret.ecr_pull | resource |
aws_secretsmanager_secret_version.ecr_pull | resource |
humanitec_application.example | resource |
humanitec_resource_definition.workload | resource |
humanitec_resource_definition_criteria.imagepullsecret | resource |
humanitec_resource_definition_criteria.workload | resource |
aws_caller_identity.current | data source |
Inputs
Name | Description | Type | Default | Required |
---|---|---|---|---|
humanitec_secret_store_id | Humanitec Secret Store ID that points to AWS Secrets Manager | string |
n/a | yes |
region | AWS Region | string |
n/a | yes |
name | Name of the example application | string |
"hum-rp-ips-example" |
no |
prefix | Prefix of the created resources | string |
"hum-rp-ips-ex-" |
no |
main.tf
(
view on GitHub
)
:
# AWS IAM user used by the k8s-cluster to pull images from ECR
resource "aws_iam_user" "cluster_ecr_pull" {
name = "cluster_ecr_pull"
}
resource "aws_iam_user_policy_attachment" "cluster_ecr_pull" {
user = aws_iam_user.cluster_ecr_pull.name
# https://docs.aws.amazon.com/AmazonECR/latest/userguide/security-iam-awsmanpol.html#security-iam-awsmanpol-AmazonEC2ContainerRegistryReadOnly
policy_arn = "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly"
}
resource "aws_iam_access_key" "cluster_ecr_pull" {
user = aws_iam_user.cluster_ecr_pull.name
# Ensure that the policy is not deleted before the access key
depends_on = [aws_iam_user_policy_attachment.cluster_ecr_pull]
}
# Store the access key and secret in AWS Secrets Manager for the Humanitec Operator to be able to fetch them.
locals {
ecr_pull_secrets = {
aws-access-key-id = aws_iam_access_key.cluster_ecr_pull.id
aws-secret-access-key = aws_iam_access_key.cluster_ecr_pull.secret
}
ecr_pull_secret_refs = {
for key, value in local.ecr_pull_secrets : key => {
ref = aws_secretsmanager_secret.ecr_pull[key].name
store = var.humanitec_secret_store_id
version = aws_secretsmanager_secret_version.ecr_pull[key].version_id
}
}
}
resource "aws_secretsmanager_secret" "ecr_pull" {
for_each = local.ecr_pull_secrets
name = "humanitec-ecr-pull-secret-${each.key}"
}
resource "aws_secretsmanager_secret_version" "ecr_pull" {
for_each = local.ecr_pull_secrets
secret_id = aws_secretsmanager_secret.ecr_pull[each.key].id
secret_string = each.value
}
# Example application and resource definition criteria
resource "humanitec_application" "example" {
id = var.name
name = var.name
}
# Current AWS Account ID
data "aws_caller_identity" "current" {}
locals {
imagepullsecret_config_res_id = "imagepullsecret"
}
module "imagepullsecret" {
source = "github.com/humanitec-architecture/resource-packs-aws?ref=v2024-06-14//humanitec-resource-defs/config/imagepullsecret"
prefix = var.prefix
account_id = data.aws_caller_identity.current.account_id
region = var.region
access_key_id_ref = local.ecr_pull_secret_refs["aws-access-key-id"]
secret_access_key_ref = local.ecr_pull_secret_refs["aws-secret-access-key"]
}
resource "humanitec_resource_definition_criteria" "imagepullsecret" {
resource_definition_id = module.imagepullsecret.id
app_id = humanitec_application.example.id
res_id = local.imagepullsecret_config_res_id
class = "default"
force_delete = true
}
resource "humanitec_resource_definition" "workload" {
driver_type = "humanitec/template"
id = "${var.prefix}workload"
name = "${var.prefix}workload"
type = "workload"
driver_inputs = {
values_string = jsonencode({
templates = {
outputs = <<EOL
update:
- op: add
path: /spec/imagePullSecrets
value:
- name: $${resources["config.default#${local.imagepullsecret_config_res_id}"].outputs.secret_name}
EOL
}
})
}
}
resource "humanitec_resource_definition_criteria" "workload" {
resource_definition_id = humanitec_resource_definition.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
)
:
# Humanitec Secret Store ID that points to AWS Secrets Manager
humanitec_secret_store_id = ""
# Name of the example application
name = "hum-rp-ips-example"
# Prefix of the created resources
prefix = "hum-rp-ips-ex-"
# AWS Region
region = ""
variables.tf
(
view on GitHub
)
:
variable "region" {
description = "AWS Region"
type = string
}
variable "name" {
description = "Name of the example application"
type = string
default = "hum-rp-ips-example"
}
variable "prefix" {
description = "Prefix of the created resources"
type = string
default = "hum-rp-ips-ex-"
}
variable "humanitec_secret_store_id" {
description = "Humanitec Secret Store ID that points to AWS Secrets Manager"
type = string
}