CNTRLPLANE-2205: feat(aws): add shared-role support for IAM operations - #7331
Conversation
Add --shared-role flag to create/destroy IAM commands to support creating a single shared IAM role with all component policies instead of individual roles for each component. This reduces the number of IAM roles from 7+ to 1. Changes: - Add SharedRole field to CreateIAMOptions and DestroyIAMOptions - Add --shared-role flag to "hypershift create iam aws" command - Add --shared-role flag to "hypershift destroy iam aws" command - Implement CreateSharedOIDCRole to create single role with multiple inline policies - Refactor DestroyOIDCRole to dynamically list and delete all inline policies, supporting both shared and individual roles - Fix credential secret creation bug: change from map to slice to support multiple secrets with same ARN when using shared roles The shared role includes all service accounts in its trust policy and contains separate inline policies for each component (ingress, image-registry, ebs-csi, cloud-controller, node-pool, control-plane-operator, network, karpenter, kms-provider). Commit-Message-Assisted-by: Claude (via Claude Code)
|
Skipping CI for Draft Pull Request. |
WalkthroughThis change introduces a new Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes
✨ Finishing touches
🧪 Generate unit tests (beta)
Comment |
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: sjenning The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
|
/lgtm |
|
/verified by @sjenning |
|
@sjenning: This PR has been marked as verified by DetailsIn response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository. |
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (1)
cmd/infra/aws/destroy_iam.go (1)
190-191: Unused parameterincludeAssumePolicyafter refactoring.The
includeAssumePolicyparameter is still passed to callers but is never used within the function body. The refactored code now dynamically lists and deletes all inline policies, making this parameter obsolete.Consider removing the unused parameter:
-func (o *DestroyIAMOptions) DestroyOIDCRole(client iamiface.IAMAPI, name string, includeAssumePolicy bool) error { +func (o *DestroyIAMOptions) DestroyOIDCRole(client iamiface.IAMAPI, name string) error {This would require updating all callers (lines 153, 158, 161, 164, 167, 170, 173, 176, 179, 182, 360, 363) to remove the boolean argument.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting
📒 Files selected for processing (7)
cmd/cluster/aws/create.go(3 hunks)cmd/cluster/aws/destroy.go(2 hunks)cmd/cluster/core/destroy.go(1 hunks)cmd/infra/aws/create_iam.go(2 hunks)cmd/infra/aws/destroy_iam.go(4 hunks)cmd/infra/aws/iam.go(2 hunks)hypershift-operator/controllers/hostedcluster/internal/platform/aws/aws.go(1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**
⚙️ CodeRabbit configuration file
-Focus on major issues impacting performance, readability, maintainability and security. Avoid nitpicks and avoid verbosity.
Files:
cmd/infra/aws/iam.gocmd/infra/aws/destroy_iam.gohypershift-operator/controllers/hostedcluster/internal/platform/aws/aws.gocmd/cluster/core/destroy.gocmd/cluster/aws/destroy.gocmd/infra/aws/create_iam.gocmd/cluster/aws/create.go
🧬 Code graph analysis (1)
cmd/infra/aws/iam.go (2)
cmd/cluster/aws/create.go (1)
CreateIAMOptions(570-588)cmd/infra/aws/create_iam.go (1)
CreateIAMOptions(28-51)
🪛 golangci-lint (2.5.0)
cmd/infra/aws/destroy_iam.go
[error] 228-228: : # github.com/openshift/hypershift/sync-global-pullsecret [github.com/openshift/hypershift/sync-global-pullsecret.test]
sync-global-pullsecret/sync-global-pullsecret_test.go:228:23: undefined: MockdbusConn
sync-global-pullsecret/sync-global-pullsecret_test.go:234:26: undefined: MockdbusConn
sync-global-pullsecret/sync-global-pullsecret_test.go:247:26: undefined: MockdbusConn
sync-global-pullsecret/sync-global-pullsecret_test.go:257:26: undefined: MockdbusConn
sync-global-pullsecret/sync-global-pullsecret_test.go:270:26: undefined: MockdbusConn
sync-global-pullsecret/sync-global-pullsecret_test.go:283:26: undefined: MockdbusConn
sync-global-pullsecret/sync-global-pullsecret_test.go:296:26: undefined: MockdbusConn
sync-global-pullsecret/sync-global-pullsecret_test.go:309:26: undefined: MockdbusConn
sync-global-pullsecret/sync-global-pullsecret_test.go:327:12: undefined: NewMockdbusConn
(typecheck)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: Red Hat Konflux / hypershift-operator-main-on-pull-request
- GitHub Check: Red Hat Konflux / hypershift-release-mce-211-on-pull-request
- GitHub Check: Red Hat Konflux / hypershift-cli-mce-211-on-pull-request
- GitHub Check: Cursor Bugbot
🔇 Additional comments (15)
cmd/cluster/core/destroy.go (1)
59-59: LGTM!The
SharedRolefield addition toAWSPlatformDestroyOptionsis correctly placed and follows the existing struct conventions. This enables proper propagation of the shared-role setting through the destroy path.cmd/cluster/aws/destroy.go (2)
37-37: LGTM!The
--shared-roleflag is correctly bound and follows the existing flag patterns in this file.
108-108: LGTM!The
SharedRolevalue is correctly propagated fromAWSPlatformoptions toDestroyIAMOptions.cmd/infra/aws/create_iam.go (2)
50-50: LGTM!The
SharedRolefield is correctly added toCreateIAMOptionsstruct, enabling the shared-role creation path.
94-94: LGTM!The
--shared-roleflag is correctly bound with a clear description matching the feature intent.cmd/cluster/aws/create.go (3)
63-63: LGTM!The
SharedRolefield correctly extendsRawCreateOptionsto support the shared-role feature in cluster creation.
506-506: LGTM!The
--shared-roleflag is correctly bound with consistent description across create commands.
586-586: LGTM!The
SharedRolevalue is correctly propagated fromawsOptstoCreateIAMOptions, completing the option chain for IAM creation.cmd/infra/aws/destroy_iam.go (4)
32-32: LGTM!The
SharedRolefield is correctly added toDestroyIAMOptions.
53-53: LGTM!The
--shared-roleflag is correctly bound with consistent description.
150-185: LGTM!The branching logic correctly handles both shared-role and individual component roles destruction paths. The shared role uses the name
"shared-role"which should match the creation side.
222-248: LGTM!The refactored inline policy deletion correctly uses
ListRolePoliciesto dynamically discover and delete all policies, which properly supports both shared roles (with multiple policies) and individual component roles.cmd/infra/aws/iam.go (2)
872-892: LGTM! Clean conditional branching for shared role feature.The implementation correctly branches between shared and individual role creation paths. The shared role ARN is properly propagated to all binding targets, and error handling is appropriate.
993-1062: LGTM! Well-structured shared role creation.The
CreateSharedOIDCRolefunction correctly:
- Deduplicates service accounts across all bindings
- Creates a unified trust policy with all service accounts
- Attaches each component's policy as a separate inline policy
- Conditionally adds the assume role policy when needed
- Provides clear logging and error messages
hypershift-operator/controllers/hostedcluster/internal/platform/aws/aws.go (1)
301-316: Good fix for the duplicate ARN issue—slice-based approach correctly preserves shared role secrets.The change from a map to a slice properly addresses the limitation where a map keyed by ARN would silently drop entries when multiple secrets share the same ARN. This implementation maintains all secret/ARN pairs and preserves the existing error aggregation behavior. Errors from missing or invalid ARNs will be caught during the
syncSecretcalls and aggregated in theerrsslice, so no additional validation is needed here.
|
@sjenning: This pull request explicitly references no jira issue. DetailsIn response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository. |
|
/override ci/prow/e2e-aws-4-20 |
|
@sjenning: Overrode contexts on behalf of sjenning: ci/prow/e2e-aws-4-20 DetailsIn response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. |
|
@sjenning: all tests passed! Full PR test history. Your PR dashboard. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here. |
|
/cherry-pick release-4.20 |
|
@devguyio: #7331 failed to apply on top of branch "release-4.20": DetailsIn response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. |
The HO shared role credential reconciliation fix (openshift#7331) only landed on 4.21+. The upgrade test runs the pre-upgrade HO image which on 4.20 still uses a map keyed by ARN, silently deduplicating credential secrets when all components share one IAM role. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Signed-off-by: Ahmed Abdalla <aabdelre@redhat.com>
Add
shared-roleflag to create/destroy IAM commands to support creating a single shared IAM role with all component policies instead of individual roles for each component. This reduces the number of IAM roles from 7+ to 1, reducing AWS API load and Roles quota issues.Changes:
The shared role includes all service accounts in its trust policy and contains separate inline policies for each component (ingress, image-registry, ebs-csi, cloud-controller, node-pool, control-plane-operator, network, karpenter, kms-provider).
Note
Adds a --shared-role option to create/destroy IAM paths to use a single aggregated IAM role, updates deletion logic accordingly, and fixes credential secret syncing for shared ARNs.
CreateSharedOIDCRoleincmd/infra/aws/iam.goto create one role (<infra-id>-shared-role) with combined trust policy and multiple inline policies; sets all role ARNs to the shared ARN.cmd/infra/aws/destroy_iam.go, addSharedRolehandling to delete the shared role or individual roles; refactorDestroyOIDCRoleto list/delete all inline policies dynamically and detach managed policies.SharedRolefield and--shared-roleflag across create/destroy commands and option structs:cmd/infra/aws/create_iam.go,cmd/infra/aws/destroy_iam.go,cmd/cluster/aws/create.go,cmd/cluster/aws/destroy.go,cmd/cluster/core/destroy.go.SharedRolethrough to IAM create/destroy options.hypershift-operator/.../platform/aws/aws.goto use a slice instead of a map, allowing multiple secrets to reference the same ARN when using a shared role.Written by Cursor Bugbot for commit 28895f2. This will update automatically on new commits. Configure here.