From b0d8e8253ccd46e8cc0e0ce6aaacbb0641ec99d3 Mon Sep 17 00:00:00 2001 From: sebas_correa Date: Tue, 9 Jun 2026 21:47:58 -0300 Subject: [PATCH 1/2] fix(ecr): remove read section and simplify setup.policy handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove cross_account_pull_role_arn variable and read block from provider config — the read section is deprecated for new installations and caused perpetual drift due to PATCH merge semantics (absent keys are preserved by the API rather than cleared) - Always include setup.policy using var.repository_policy directly instead of a conditional merge — the nullplatform API preserves empty strings as-is, avoiding drift when cross-account pull is disabled - Refactor attributes into a local for readability Co-Authored-By: Claude Sonnet 4.6 --- nullplatform/asset/ecr/main.tf | 40 ++++++++++++----------------- nullplatform/asset/ecr/variables.tf | 6 ----- 2 files changed, 17 insertions(+), 29 deletions(-) diff --git a/nullplatform/asset/ecr/main.tf b/nullplatform/asset/ecr/main.tf index 9313202a..b999a210 100644 --- a/nullplatform/asset/ecr/main.tf +++ b/nullplatform/asset/ecr/main.tf @@ -1,28 +1,22 @@ +locals { + setup = { + region = data.aws_region.current.region + role_arn = var.application_role_arn + naming_rule = var.naming_rule + policy = var.repository_policy + } +} + resource "nullplatform_provider_config" "ecr" { provider = nullplatform nrn = var.nrn type = "ecr" - attributes = jsonencode(merge( - { - "ci" : { - "region" : data.aws_region.current.region, - "access_key" : var.build_workflow_access_key_id, - "secret_key" : var.build_workflow_access_key_secret - }, - "setup" : merge( - { - "region" : data.aws_region.current.region, - "role_arn" : var.application_role_arn, - "naming_rule" : var.naming_rule, - }, - var.repository_policy != "" ? { "policy" : var.repository_policy } : {} - ) - }, - var.cross_account_pull_role_arn != "" ? { - "read" : { - "region" : data.aws_region.current.region, - "role_arn" : var.cross_account_pull_role_arn - } - } : {} - )) + attributes = jsonencode({ + ci = { + region = data.aws_region.current.region + access_key = var.build_workflow_access_key_id + secret_key = var.build_workflow_access_key_secret + } + setup = local.setup + }) } diff --git a/nullplatform/asset/ecr/variables.tf b/nullplatform/asset/ecr/variables.tf index 5a6b31b7..90b54263 100644 --- a/nullplatform/asset/ecr/variables.tf +++ b/nullplatform/asset/ecr/variables.tf @@ -25,12 +25,6 @@ variable "build_workflow_access_key_secret" { sensitive = true } -variable "cross_account_pull_role_arn" { - description = "ARN of the IAM role for cross-account ECR pull access (maps to 'read.role_arn' in provider config). Leave empty to omit the read section." - type = string - default = "" -} - variable "repository_policy" { description = "ECR repository policy JSON applied to every new repository Nullplatform creates (maps to 'setup.policy'). Leave empty to omit." type = string From d1b1f564e0173391cac34bb05e1216f65ef9a3e4 Mon Sep 17 00:00:00 2001 From: sebas_correa Date: Wed, 10 Jun 2026 14:23:58 -0300 Subject: [PATCH 2/2] fix(iam/ecr): remove cross-account pull role creation The ecr_cross_account_pull role was used exclusively to populate read.role_arn in the nullplatform provider config, which is a deprecated installation pattern. Cross-account pull is now handled entirely via ECR repository policy (setup.policy), making this role orphaned. Co-Authored-By: Claude Sonnet 4.6 --- infrastructure/aws/iam/ecr/main.tf | 48 --------------------------- infrastructure/aws/iam/ecr/outputs.tf | 5 --- 2 files changed, 53 deletions(-) diff --git a/infrastructure/aws/iam/ecr/main.tf b/infrastructure/aws/iam/ecr/main.tf index 68473e7e..acab5d2f 100644 --- a/infrastructure/aws/iam/ecr/main.tf +++ b/infrastructure/aws/iam/ecr/main.tf @@ -71,51 +71,3 @@ resource "aws_iam_user_group_membership" "build_workflow_ecr_managers" { groups = [aws_iam_group.nullplatform_ecr_managers.name] } -resource "aws_iam_role" "ecr_cross_account_pull" { - count = var.enable_cross_account_pull ? 1 : 0 - name = "nullplatform-${var.cluster_name}-ecr-cross-account-pull" - - assume_role_policy = jsonencode({ - Version = "2012-10-17" - Statement = [{ - Effect = "Allow" - Principal = { - AWS = [for id in var.pull_account_ids : "arn:aws:iam::${id}:root"] - } - Action = "sts:AssumeRole" - }] - }) -} - -resource "aws_iam_policy" "ecr_cross_account_pull" { - count = var.enable_cross_account_pull ? 1 : 0 - name = "nullplatform-${var.cluster_name}-ecr-cross-account-pull-policy" - description = "Allows cross-account principals to pull images from ECR" - policy = jsonencode({ - Version = "2012-10-17" - Statement = [ - { - Effect = "Allow" - Action = [ - "ecr:GetDownloadUrlForLayer", - "ecr:BatchGetImage", - "ecr:BatchCheckLayerAvailability", - "ecr:DescribeImages", - "ecr:DescribeRepositories" - ] - Resource = "arn:aws:ecr:*:*:repository/*" - }, - { - Effect = "Allow" - Action = ["ecr:GetAuthorizationToken"] - Resource = "*" - } - ] - }) -} - -resource "aws_iam_role_policy_attachment" "ecr_cross_account_pull" { - count = var.enable_cross_account_pull ? 1 : 0 - role = aws_iam_role.ecr_cross_account_pull[0].name - policy_arn = aws_iam_policy.ecr_cross_account_pull[0].arn -} diff --git a/infrastructure/aws/iam/ecr/outputs.tf b/infrastructure/aws/iam/ecr/outputs.tf index e215215f..c6274d95 100644 --- a/infrastructure/aws/iam/ecr/outputs.tf +++ b/infrastructure/aws/iam/ecr/outputs.tf @@ -14,11 +14,6 @@ output "build_workflow_access_key_secret" { sensitive = true } -output "cross_account_pull_role_arn" { - description = "ARN of the IAM role that cross-account principals can assume to pull ECR images. Empty string when enable_cross_account_pull is false." - value = var.enable_cross_account_pull ? aws_iam_role.ecr_cross_account_pull[0].arn : "" -} - output "ecr_repository_policy" { description = "ECR repository policy JSON granting pull access to the configured cross-account IDs. Empty string when enable_cross_account_pull is false." value = var.enable_cross_account_pull ? jsonencode({