Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
# Changelog

## [5.0.0](https://github.com/nullplatform/tofu-modules/compare/v4.6.0...v5.0.0) (2026-06-25)


### ⚠ BREAKING CHANGES

* **iam:** infrastructure/aws/iam/ecr no longer creates the build workflow user, access key or group, and no longer outputs build_workflow_access_key_id / build_workflow_access_key_secret. Consumers must instantiate the new build-user module, pass its group_name to ecr (new required input build_workflow_group_name) and to s3-assets, take the build credentials from build-user outputs, and run a tofu state mv to preserve the existing user and access key (see infrastructure/aws/iam/build-user/README.md). The IAM group is renamed from ecr-managers to asset-publishers (recreated; does not rotate the user's keys).

### Features

* **iam:** separate build workflow user from asset repositories + add S3 asset support ([#402](https://github.com/nullplatform/tofu-modules/issues/402)) ([9ae9e09](https://github.com/nullplatform/tofu-modules/commit/9ae9e095e5090d08508b97e6ec4da1a1b7e2ab6a))

## [4.6.0](https://github.com/nullplatform/tofu-modules/compare/v4.5.2...v4.6.0) (2026-06-25)


Expand Down
2 changes: 1 addition & 1 deletion infrastructure/aws/acm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ The module creates an aws_acm_certificate resource with DNS validation, which is

```hcl
module "acm" {
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/acm?ref=v4.6.0"
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/acm?ref=v5.0.0"

domain_name = "your-domain-name"
zone_id = "your-zone-id"
Expand Down
2 changes: 1 addition & 1 deletion infrastructure/aws/aws_load_balancer_controller/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ This module creates a helm_release resource to deploy the AWS Load Balancer Cont

```hcl
module "aws_load_balancer_controller" {
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/aws_load_balancer_controller?ref=v4.6.0"
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/aws_load_balancer_controller?ref=v5.0.0"

cluster_name = "your-cluster-name"
vpc_id = "your-vpc-id"
Expand Down
2 changes: 1 addition & 1 deletion infrastructure/aws/backend/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ This module creates an S3 bucket with versioning and server-side encryption enab

```hcl
module "backend" {
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/backend?ref=v4.6.0"
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/backend?ref=v5.0.0"
}
```

Expand Down
2 changes: 1 addition & 1 deletion infrastructure/aws/dns/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ The module conditionally creates an aws_route53_zone resource for a public hoste

```hcl
module "dns" {
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/dns?ref=v4.6.0"
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/dns?ref=v5.0.0"

domain_name = "your-domain-name"
vpc_id = "your-vpc-id"
Expand Down
2 changes: 1 addition & 1 deletion infrastructure/aws/eks/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ The module wraps terraform-aws-modules/eks to create the EKS cluster (aws_eks_cl

```hcl
module "eks" {
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/eks?ref=v4.6.0"
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/eks?ref=v5.0.0"

aws_subnets_private_ids = "your-aws-subnets-private-ids"
aws_vpc_vpc_id = "your-aws-vpc-vpc-id"
Expand Down
2 changes: 1 addition & 1 deletion infrastructure/aws/iam/agent/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ The module uses the terraform-aws-modules/iam//modules/iam-role-for-service-acco

```hcl
module "agent" {
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/iam/agent?ref=v4.6.0"
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/iam/agent?ref=v5.0.0"

agent_namespace = "your-agent-namespace"
aws_iam_openid_connect_provider_arn = "your-aws-iam-openid-connect-provider-arn"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ This module creates an IAM role for the AWS Load Balancer Controller using the t

```hcl
module "aws_load_balancer_controller_iam" {
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/iam/aws_load_balancer_controller_iam?ref=v4.6.0"
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/iam/aws_load_balancer_controller_iam?ref=v5.0.0"

aws_iam_openid_connect_provider_arn = "your-aws-iam-openid-connect-provider-arn"
cluster_name = "your-cluster-name"
Expand Down
2 changes: 1 addition & 1 deletion infrastructure/aws/iam/cert_manager/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ An aws_iam_policy is created granting Route53 permissions (GetChange, ChangeReso

```hcl
module "cert_manager" {
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/iam/cert_manager?ref=v4.6.0"
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/iam/cert_manager?ref=v5.0.0"

aws_iam_openid_connect_provider_arn = "your-aws-iam-openid-connect-provider-arn"
cluster_name = "your-cluster-name"
Expand Down
90 changes: 44 additions & 46 deletions infrastructure/aws/iam/ci-build-workflow-user/README.md
Original file line number Diff line number Diff line change
@@ -1,72 +1,41 @@
# Module: build-user
# Module: ci-build-workflow-user

## Description

Provisions the shared CI/CD build workflow IAM identity (user, access key, and group) used to publish application assets to any asset repository (ECR, S3, etc.)
Creates an AWS IAM user with access keys and an IAM group for CI/CD build workflow asset publishing in a nullplatform cluster

## Architecture

The module creates a single `aws_iam_user` with an `aws_iam_access_key` for CI/CD build workflows, plus an `aws_iam_group` named `asset-publishers` and the `aws_iam_user_group_membership` that adds the user to it. The group is the attachment point for per-destination permission modules: `infrastructure/aws/iam/ecr` attaches its ECR policy to this group, and `infrastructure/aws/iam/s3-assets` attaches its S3 policy to the same group. The build user therefore accumulates the permissions of every enabled destination through a single group, which matches how the platform CLI publishes assets (one credential set used for all asset types).
The module creates an aws_iam_user named with the cluster_name prefix and generates an aws_iam_access_key for programmatic access. An aws_iam_group is created to serve as the attachment point for downstream policy modules such as ECR or S3 asset repositories. An aws_iam_user_group_membership resource wires the build workflow user into the asset publishers group, and the access key credentials along with the group name are exposed as outputs for consumption by other modules.

## Features

- Creates a single namespaced `aws_iam_user` and `aws_iam_access_key` for CI/CD build workflow authentication
- Creates a destination-agnostic `aws_iam_group` (`asset-publishers`) that permission modules attach their policies to
- Adds the build user to the group via `aws_iam_user_group_membership`
- Exposes `group_name` so asset-repository modules (`ecr`, `s3-assets`) can grant permissions without recreating the identity
- Creates a namespaced aws_iam_user for CI/CD build workflow automation scoped to the cluster name
- Generates aws_iam_access_key credentials for programmatic AWS API access by the build workflow user
- Creates an aws_iam_group to serve as a shared attachment point for asset-publishing IAM policies
- Attaches the build workflow user to the asset publishers group via aws_iam_user_group_membership
- Outputs access key ID and sensitive secret key for use in CI/CD pipeline configuration
- Exposes the IAM group name output for policy attachment by downstream ECR and S3 asset modules

## Basic Usage

```hcl
module "build_user" {
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/iam/build-user?ref=v5.0.0"
module "ci-build-workflow-user" {
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/iam/ci-build-workflow-user?ref=v5.0.0"

cluster_name = "your-cluster-name"
}
```

The `group_name` output is consumed by the asset-repository permission modules:
## Using Outputs

```hcl
module "ecr" {
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/iam/ecr?ref=v5.0.0"

cluster_name = "your-cluster-name"
build_workflow_group_name = module.build_user.group_name
}

module "s3_assets" {
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/iam/s3-assets?ref=v5.0.0"

cluster_name = "your-cluster-name"
build_workflow_group_name = module.build_user.group_name
assets_bucket = "your-assets-bucket"
# Reference outputs in other resources
resource "example_resource" "this" {
example_attribute = module.ci-build-workflow-user.build_workflow_access_key_id
}
```

## Migration from < v5.0.0 (build user previously created by `iam/ecr`)

Before v5.0.0 the build workflow user, its access key and the group lived inside the `iam/ecr`
module. This module extracts them. To migrate **without rotating the access keys** (which would
break CI), move the user and its access key in state — the group is renamed
(`ecr-managers` → `asset-publishers`) and is recreated, which does not affect the user's credentials:

```bash
tofu state mv 'module.ecr.aws_iam_user.nullplatform_build_workflow_user' \
'module.build_user.aws_iam_user.nullplatform_build_workflow_user'

tofu state mv 'module.ecr.aws_iam_access_key.nullplatform_build_workflow_user_key' \
'module.build_user.aws_iam_access_key.nullplatform_build_workflow_user_key'
```

After the moves, a `tofu plan` should show **no changes** to the user and access key (only their
state address moved), the group + membership recreated as `asset-publishers`, and the ECR policy
re-attached to the new group.

> **Security note:** the build credentials are read by the platform on each CI run (they are not
> stored as per-repository secrets), so rotating them periodically is a good practice and this
> module makes it easy — regenerate the access key and let the platform re-read the new value.

<!-- BEGIN_TF_DOCS -->


Expand Down Expand Up @@ -99,3 +68,32 @@ re-attached to the new group.
| <a name="output_build_workflow_access_key_secret"></a> [build\_workflow\_access\_key\_secret](#output\_build\_workflow\_access\_key\_secret) | Secret access key for the CI/CD build workflow IAM user |
| <a name="output_group_name"></a> [group\_name](#output\_group\_name) | Name of the IAM group that asset-repository permission modules (ecr, s3-assets) attach their policies to. The build workflow user is a member of this group. |
<!-- END_TF_DOCS -->

<!-- BEGIN_AI_METADATA
{
"name": "ci-build-workflow-user",
"description": "Creates an AWS IAM user with access keys and an IAM group for CI/CD build workflow asset publishing in a nullplatform cluster",
"architecture": "The module creates an aws_iam_user named with the cluster_name prefix and generates an aws_iam_access_key for programmatic access. An aws_iam_group is created to serve as the attachment point for downstream policy modules such as ECR or S3 asset repositories. An aws_iam_user_group_membership resource wires the build workflow user into the asset publishers group, and the access key credentials along with the group name are exposed as outputs for consumption by other modules.",
"features": [
"Creates a namespaced aws_iam_user for CI/CD build workflow automation scoped to the cluster name",
"Generates aws_iam_access_key credentials for programmatic AWS API access by the build workflow user",
"Creates an aws_iam_group to serve as a shared attachment point for asset-publishing IAM policies",
"Attaches the build workflow user to the asset publishers group via aws_iam_user_group_membership",
"Outputs access key ID and sensitive secret key for use in CI/CD pipeline configuration",
"Exposes the IAM group name output for policy attachment by downstream ECR and S3 asset modules"
],
"inputs": [
{
"name": "cluster_name",
"description": "Name of the cluster, used to namespace IAM resource names",
"required": true
}
],
"outputs": [
"build_workflow_access_key_id",
"build_workflow_access_key_secret",
"group_name"
],
"hash": "2c0aef02dbbd6af2dd32f8a3a9f60802"
}
END_AI_METADATA -->
42 changes: 16 additions & 26 deletions infrastructure/aws/iam/ecr/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,31 @@

## Description

Provisions IAM resources for ECR image management and optional cross-account ECR pull access within a named cluster namespace. The build workflow identity (user, access key, group) lives in the `ci-build-workflow-user` module; this module only grants ECR permissions to that group.
Creates IAM roles and policies for managing ECR repositories and enabling cross-account image pull access in a nullplatform cluster

## Architecture

The module creates an aws_iam_role (application role with a configurable assume-role principal) and an aws_iam_policy for ECR management actions. The ECR manager policy is attached to the application role via aws_iam_role_policy_attachment and to the shared build-workflow group via aws_iam_group_policy_attachment. The group itself is created by the `ci-build-workflow-user` module and passed in through `build_workflow_group_name`. When enable_cross_account_pull is true, a separate aws_iam_role and aws_iam_policy scoped to read-only ECR actions are created and linked, with pull_account_ids driving the Principal trust statements.
The module creates an aws_iam_role named nullplatform-{cluster_name}-application-role with a trust policy allowing a configurable application manager role to assume it. An aws_iam_policy granting ECR repository management actions (create, delete, push, pull) is created and attached to the application role via aws_iam_role_policy_attachment, and also attached to an existing IAM group via aws_iam_group_policy_attachment. The ecr_repository_policy output conditionally renders a cross-account ECR repository policy JSON granting pull access to specified AWS account IDs when enable_cross_account_pull is true.

## Features

- Creates a namespaced aws_iam_role for application image pulling with a configurable assume-role principal
- Creates an aws_iam_policy granting full ECR repository lifecycle permissions including push, pull, and repository management
- Attaches the ECR manager policy to the shared build-workflow group (created by the ci-build-workflow-user module) for group-based permission management
- Optionally creates a cross-account aws_iam_role and read-only ECR pull policy for external AWS accounts
- Outputs a ready-to-use ECR repository policy JSON for cross-account pull access configuration
- Creates aws_iam_role for application workloads with configurable assume-role trust policy
- Creates aws_iam_policy granting full ECR repository lifecycle management including push, pull, create, and delete actions
- Attaches ECR manager policy to the application role via aws_iam_role_policy_attachment
- Attaches ECR manager policy to an existing IAM group via aws_iam_group_policy_attachment for CI build workflow users
- Generates cross-account ECR repository policy JSON allowing specified AWS accounts to pull images when enable_cross_account_pull is enabled

## Basic Usage

```hcl

module "ci_build_workflow_user" {
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/iam/ci-build-workflow-user?ref=v5.0.0"
cluster_name = "your-cluster-name"
}

module "ecr" {
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/iam/ecr?ref=v5.0.0"

build_workflow_group_name = "your-build-workflow-group-name"
cluster_name = "your-cluster-name"
build_workflow_group_name = module.ci_build_workflow_user.group_name
}
```

> **Migration from < v5.0.0:** the build workflow user, access key and group were previously
> created by this module. They now live in `ci-build-workflow-user`. See that module's README for the
> `tofu state mv` steps to migrate without rotating the access keys.

## Using Outputs

```hcl
Expand Down Expand Up @@ -87,14 +77,14 @@ resource "example_resource" "this" {
<!-- BEGIN_AI_METADATA
{
"name": "ecr",
"description": "Provisions IAM resources for ECR image management and optional cross-account ECR pull access within a named cluster namespace. The build workflow identity (user, access key, group) lives in the ci-build-workflow-user module; this module only grants ECR permissions to that group.",
"architecture": "The module creates an aws_iam_role (application role with a configurable assume-role principal) and an aws_iam_policy for ECR management actions. The ECR manager policy is attached to the application role via aws_iam_role_policy_attachment and to the shared build-workflow group via aws_iam_group_policy_attachment. The group itself is created by the ci-build-workflow-user module and passed in through build_workflow_group_name. When enable_cross_account_pull is true, a separate aws_iam_role and aws_iam_policy scoped to read-only ECR actions are created and linked, with pull_account_ids driving the Principal trust statements.",
"description": "Creates IAM roles and policies for managing ECR repositories and enabling cross-account image pull access in a nullplatform cluster",
"architecture": "The module creates an aws_iam_role named nullplatform-{cluster_name}-application-role with a trust policy allowing a configurable application manager role to assume it. An aws_iam_policy granting ECR repository management actions (create, delete, push, pull) is created and attached to the application role via aws_iam_role_policy_attachment, and also attached to an existing IAM group via aws_iam_group_policy_attachment. The ecr_repository_policy output conditionally renders a cross-account ECR repository policy JSON granting pull access to specified AWS account IDs when enable_cross_account_pull is true.",
"features": [
"Creates a namespaced aws_iam_role for application image pulling with a configurable assume-role principal",
"Creates an aws_iam_policy granting full ECR repository lifecycle permissions including push, pull, and repository management",
"Attaches the ECR manager policy to the shared build-workflow group (created by the ci-build-workflow-user module) for group-based permission management",
"Optionally creates a cross-account aws_iam_role and read-only ECR pull policy for external AWS accounts",
"Outputs a ready-to-use ECR repository policy JSON for cross-account pull access configuration"
"Creates aws_iam_role for application workloads with configurable assume-role trust policy",
"Creates aws_iam_policy granting full ECR repository lifecycle management including push, pull, create, and delete actions",
"Attaches ECR manager policy to the application role via aws_iam_role_policy_attachment",
"Attaches ECR manager policy to an existing IAM group via aws_iam_group_policy_attachment for CI build workflow users",
"Generates cross-account ECR repository policy JSON allowing specified AWS accounts to pull images when enable_cross_account_pull is enabled"
],
"inputs": [
{
Expand Down Expand Up @@ -127,6 +117,6 @@ resource "example_resource" "this" {
"application_role_arn",
"ecr_repository_policy"
],
"hash": "regenerate-with-terraform-docs"
"hash": "60331cc847b22eed0125b050bbcbec83"
}
END_AI_METADATA -->
2 changes: 1 addition & 1 deletion infrastructure/aws/iam/external_dns/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ The module creates an aws_iam_policy granting Route53 permissions scoped to the

```hcl
module "external_dns" {
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/iam/external_dns?ref=v4.6.0"
source = "git::https://github.com/nullplatform/tofu-modules.git//infrastructure/aws/iam/external_dns?ref=v5.0.0"

aws_iam_openid_connect_provider_arn = "your-aws-iam-openid-connect-provider-arn"
cluster_name = "your-cluster-name"
Expand Down
Loading