Skip to content

ROSAENG-60886: Migrate from EKS Auto Mode to OSS Karpenter - #727

Closed
theautoroboto wants to merge 19 commits into
openshift-online:mainfrom
theautoroboto:remove-auto-mode-v2
Closed

ROSAENG-60886: Migrate from EKS Auto Mode to OSS Karpenter#727
theautoroboto wants to merge 19 commits into
openshift-online:mainfrom
theautoroboto:remove-auto-mode-v2

Conversation

@theautoroboto

@theautoroboto theautoroboto commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Replaces EKS Auto Mode with OSS Karpenter for MC and RC node provisioning
  • Moves kms:CreateGrant from node role to Karpenter controller role
  • Waits for hypershift Application to be Healthy before ECS bootstrap exits
  • Fixes hypershift-install Job CRD wait: kubectl not in hypershift-operator image; replaced with curl against in-cluster API server
  • Fixes monitoring bootstrap failure: tls.enabled must be disabled alongside admissionWebhooks.enabled to avoid missing TLS secret mount crash
  • Adds AWS Load Balancer Controller with TargetGroupBinding API version corrections
  • Adds MC/RC infrastructure validation scripts

Supersedes #698 (CI integration broke after history squash).

Test plan

  • /test on-demand-e2e
  • Confirm mc01-bootstrap shows === Prometheus Operator CRDs present — proceeding with hypershift install ===
  • Confirm monitoring Application reaches Healthy
  • Confirm hypershift Application reaches Healthy
  • Confirm hosted cluster provisioning succeeds end-to-end

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added OSS Karpenter-based node provisioning with bootstrap capacity, interruption handling, and FIPS-compatible workload support.
    • Added AWS Load Balancer Controller deployment and Pod Identity integration.
    • Improved cluster bootstrap sequencing, readiness checks, diagnostics, and retry handling.
    • Enabled workloads to run on tainted bootstrap nodes and updated storage provisioning.
  • Bug Fixes
    • Reduced Argo CD drift caused by controller-managed fields.
    • Updated load balancer resource compatibility.
  • Documentation
    • Added Karpenter and load balancer controller design and module documentation.

theautoroboto and others added 18 commits July 30, 2026 14:48
Replaces EKS Auto Mode with OSS Karpenter across all EKS clusters. Includes
boot ordering fixes (HyperShift CRD wait, hypershift Application health gate),
external-dns fixes (crash fix, CriticalAddonsOnly toleration, remove readiness
wait), TargetGroupBinding API version corrections, and e2e test timeout tuning.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Fix ami_kms_key_arn description (kms:CreateGrant + kms:DescribeKey on
  controller role only; remove incorrect kms:Decrypt and node-role claims)
- Remove false admission webhook claim from karpenter-node-provisioning.md
- Remove IRSA deprecated claim from zoa-trusted-actions.md
- PIPELINE_COMPLETION_TIMEOUT: 5400 → 4500 (90 min → 75 min)
- register.sh MAX_RETRIES: 80 → 10 (revert Karpenter migration increase)
- Delete unused validate-{mc,rc}-{aws,k8s}.sh scripts

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ctions

The import used `2>/dev/null || true`, which swallowed all errors. When
the import failed (e.g. state lock, resource already managed by a
concurrent run sharing the same state key), execution continued to
`terraform apply`, which found no connection in state and created a new
PENDING one — requiring manual re-authorization on every affected run.

Now the import output is captured and re-emitted on failure. The only
tolerated failure is "Resource already managed" (idempotent import);
all other errors exit non-zero with a visible message.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Drop all temporary [DNS-DEBUG] and [DIAG] blocks added during
external-dns root cause investigation:
- provision-infra-rc.sh: DNS-DEBUG echo blocks around terraform apply
- bastion/log-collection-task.tf: VPC-side DNS diag block, BASE_DOMAIN
  env var, and route53-read IAM policy
- ecs-bootstrap/main.tf: periodic hypershift-install Job/pod dump in
  the ArgoCD health wait loop

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The readyReplicas check skipped reinstall only when the deployment was
healthy, causing Karpenter to be reinstalled on any partial/pending
state. Checking helm release status is the correct idempotency boundary
— if the release is already deployed, skip.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Always-applying the NodePool conflicts with ArgoCD's SSA ownership on
resync runs. The correct pattern is to seed once on first boot and let
ArgoCD own the resource thereafter, matching main branch behavior.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Pre-warming a pause pod to surface EC2 API rate limiting is a CI
concern, not a bootstrap responsibility. App pod scheduling naturally
triggers Karpenter node provisioning. The 8-minute wait added
unnecessary latency to every bootstrap run.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ecovery and annotation re-stamping

Both the broken-release recovery and annotation re-stamping only exist
because ArgoCD was always upgraded via helm upgrade --install on every
bootstrap run. Restoring skip-if-exists (matching main branch) makes
those steps unreachable: a clean first install never ends in failed
state, and Helm annotations are never stripped because ArgoCD does not
run a competing upgrade on resources it does not yet own.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
All ArgoCD component tolerations are already defined in values.yaml and
applied automatically by helm install. The 27 redundant --set flags were
duplicating that config. Only redisSecretInit tolerations remain as
--set flags because that job is not covered by the ArgoCD chart's
default toleration keys.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The wait is not a fundamental bootstrap responsibility — it exists
because the E2E test runner starts immediately after bootstrap exits.
Label it explicitly so future readers don't treat it as a correctness
requirement for production deployments.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The HCP e2e test fails with "no such host" for the cluster API hostname
when external-dns hasn't written the Route53 A record yet. Add a
diag_dns() function called pre-test and post-failure to surface:
- external-dns pod state and recent log lines (errors/warnings)
- DNSEndpoint CRs on the MC (confirms CPO output)
- Pod Identity associations for the external-dns SA
- Route53 hosted zones in the RC account
- NS delegation for the base domain
- Targeted A record probe for the specific cluster API host (on failure)

This distinguishes IAM failures, missing DNSEndpoint CRs, Route53 zone
misconfiguration, and pure propagation timing without requiring SSH access.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ndling

- Switch command shell from /bin/sh to /bin/bash
- Log hypershift install start and exit code for easier CI triage
- Log hypershift namespace HTTP check result
- Change external-dns deployment and clusterrole patches from curl -sf
  (fail-fast) to curl -s with explicit HTTP code capture; log a WARNING
  on non-200/201 rather than aborting the Job — patch failures are
  non-fatal when the namespace already exists
- Strip stale "(Auto Mode)" text from Valkey security group descriptions

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
validate-rc-k8s.sh and validate-mc-k8s.sh (and their AWS counterparts)
require kubectl access to private EKS endpoints that Prow cannot reach.
Remove all four scripts and the k8s validation block in ci/e2e-tests.sh
that called them, fixing the validate=1 CI failure on PR openshift-online#698.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The hypershift-install Job was stuck in CreateContainerConfigError because
it referenced env vars from Secret hypershift-config-env, which is only
created by the CSI Secrets Store driver after a pod successfully mounts
the CSI volume. Kubernetes validates Secret references before starting the
pod, creating a deadlock: pod won't start without the Secret, Secret won't
be created without the pod mounting the volume.

Fix by reading OIDC configuration directly from CSI-mounted files
(/mnt/secrets-store/*) instead of relying on the Kubernetes Secret object.
The pod can now start (no Secret reference to validate), mount the CSI
volume, read the files, and proceed.

Changes:
- Remove env vars OIDC_BUCKET_NAME, OIDC_BUCKET_REGION, OIDC_WRITER_ROLE_ARN
  that referenced secretKeyRef hypershift-config-env
- Add shell commands to read values from CSI-mounted files at script start
- Update hypershift install command to use shell variables instead of
  command substitution syntax

Fixes: bda1a13 (feat: refactor OIDC S3/KMS access to assume-role pattern)
Resolves: Management Cluster provision timeout in ephemeral CI runs

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Jul 30, 2026
@openshift-ci-robot

openshift-ci-robot commented Jul 30, 2026

Copy link
Copy Markdown
Collaborator

@theautoroboto: This pull request references ROSAENG-60886 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the epic to target the "5.0.0" version, but no target version was set.

Details

In response to this:

Summary

  • Replaces EKS Auto Mode with OSS Karpenter for MC and RC node provisioning
  • Moves kms:CreateGrant from node role to Karpenter controller role
  • Waits for hypershift Application to be Healthy before ECS bootstrap exits
  • Fixes hypershift-install Job CRD wait: kubectl not in hypershift-operator image; replaced with curl against in-cluster API server
  • Fixes monitoring bootstrap failure: tls.enabled must be disabled alongside admissionWebhooks.enabled to avoid missing TLS secret mount crash
  • Adds AWS Load Balancer Controller with TargetGroupBinding API version corrections
  • Adds MC/RC infrastructure validation scripts

Supersedes #698 (CI integration broke after history squash).

Test plan

  • /test on-demand-e2e
  • Confirm mc01-bootstrap shows === Prometheus Operator CRDs present — proceeding with hypershift install ===
  • Confirm monitoring Application reaches Healthy
  • Confirm hypershift Application reaches Healthy
  • Confirm hosted cluster provisioning succeeds end-to-end

🤖 Generated with Claude Code

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.

@openshift-ci

openshift-ci Bot commented Jul 30, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign cdoan1 for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 611a9069-f34c-42ba-951f-90f1b6afd896

📥 Commits

Reviewing files that changed from the base of the PR and between 211f9b7 and 1dde297.

📒 Files selected for processing (73)
  • .gitignore
  • Makefile
  • argocd/config/management-cluster/eks-nodepool/templates/00-nodeclass.yaml
  • argocd/config/management-cluster/eks-nodepool/templates/10-nodepool.yaml
  • argocd/config/management-cluster/eks-nodepool/values.yaml
  • argocd/config/management-cluster/hypershift/templates/05-job.yaml
  • argocd/config/management-cluster/monitoring/values.yaml
  • argocd/config/regional-cluster/aws-load-balancer-controller/Chart.yaml
  • argocd/config/regional-cluster/aws-load-balancer-controller/values.yaml
  • argocd/config/regional-cluster/eks-nodepool/templates/00-nodeclass.yaml
  • argocd/config/regional-cluster/eks-nodepool/templates/10-nodepool.yaml
  • argocd/config/regional-cluster/eks-nodepool/values.yaml
  • argocd/config/regional-cluster/grafana/templates/sre-targetgroupbinding.yaml
  • argocd/config/regional-cluster/loki/templates/targetgroupbinding.yaml
  • argocd/config/regional-cluster/monitoring/templates/sre-targetgroupbinding.yaml
  • argocd/config/regional-cluster/monitoring/values.yaml
  • argocd/config/regional-cluster/platform-api/templates/targetgroupbinding.yaml
  • argocd/config/regional-cluster/thanos/templates/targetgroupbinding.yaml
  • argocd/config/shared/argocd/templates/sre-targetgroupbinding.yaml
  • argocd/config/shared/argocd/values.yaml
  • argocd/config/shared/storageclass/templates/gp3.yaml
  • ci/e2e-tests.sh
  • ci/ephemeral-provider/__init__.py
  • ci/ephemeral-provider/orchestrator.py
  • config/templates/argocd-bootstrap/applicationset.yaml.j2
  • deploy/ephemeral/us-east-1/argocd-bootstrap-management-cluster/applicationset.yaml
  • deploy/ephemeral/us-east-1/argocd-bootstrap-regional-cluster/applicationset.yaml
  • deploy/integration/us-east-1/argocd-bootstrap-management-cluster/applicationset.yaml
  • deploy/integration/us-east-1/argocd-bootstrap-regional-cluster/applicationset.yaml
  • docs/README.md
  • docs/design/fips-eks-compute.md
  • docs/design/fully-private-eks-bootstrap.md
  • docs/design/karpenter-node-provisioning.md
  • docs/design/logging-platform.md
  • docs/design/thanos-metrics-infrastructure.md
  • docs/design/zoa-trusted-actions.md
  • scripts/buildspec/bootstrap-argocd-mc.sh
  • scripts/buildspec/provision-infra-mc.sh
  • scripts/buildspec/provision-infra-rc.sh
  • scripts/buildspec/register.sh
  • scripts/verify-fips.sh
  • terraform/config/management-cluster/main.tf
  • terraform/config/pipeline-management-cluster/main.tf
  • terraform/config/pipeline-regional-cluster/main.tf
  • terraform/config/regional-cluster/imports.sh
  • terraform/config/regional-cluster/main.tf
  • terraform/modules/api-gateway/alb.tf
  • terraform/modules/api-gateway/variables.tf
  • terraform/modules/aws-load-balancer-controller/README.md
  • terraform/modules/aws-load-balancer-controller/iam.tf
  • terraform/modules/aws-load-balancer-controller/main.tf
  • terraform/modules/aws-load-balancer-controller/outputs.tf
  • terraform/modules/aws-load-balancer-controller/variables.tf
  • terraform/modules/aws-load-balancer-controller/versions.tf
  • terraform/modules/bastion/log-collection-task.tf
  • terraform/modules/ecs-bootstrap/README.md
  • terraform/modules/ecs-bootstrap/main.tf
  • terraform/modules/ecs-bootstrap/variables.tf
  • terraform/modules/eks-cluster/README.md
  • terraform/modules/eks-cluster/data.tf
  • terraform/modules/eks-cluster/iam.tf
  • terraform/modules/eks-cluster/locals.tf
  • terraform/modules/eks-cluster/main.tf
  • terraform/modules/eks-cluster/outputs.tf
  • terraform/modules/eks-cluster/variables.tf
  • terraform/modules/eks-cluster/versions.tf
  • terraform/modules/elasticache-valkey/main.tf
  • terraform/modules/elasticache-valkey/variables.tf
  • terraform/modules/rhobs-api-gateway/README.md
  • terraform/modules/rhobs-api-gateway/alb.tf
  • terraform/modules/rhobs-api-gateway/variables.tf
  • terraform/modules/sre-ui-alb/alb.tf
  • terraform/modules/sre-ui-alb/variables.tf

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to data retention organization setting


📝 Walkthrough

Walkthrough

The change migrates EKS clusters from Auto Mode to OSS Karpenter, adds AWS Load Balancer Controller provisioning, updates bootstrap and Argo CD behavior, changes TargetGroupBinding APIs, and expands CI validation, diagnostics, and documentation.

Changes

Karpenter infrastructure and bootstrap

Layer / File(s) Summary
Karpenter cluster infrastructure
terraform/modules/eks-cluster/*
Adds Karpenter IAM, IRSA, interruption queues, bootstrap capacity, addon ordering, EBS CSI Pod Identity, lifecycle cleanup, and module outputs.
Bootstrap orchestration
terraform/modules/ecs-bootstrap/*, terraform/config/*/main.tf
Installs and validates Karpenter before Argo CD, passes controller and queue values, and waits for management-cluster Hypershift readiness.
Karpenter node manifests
argocd/config/*/eks-nodepool/*, Makefile, scripts/verify-fips.sh
Migrates NodeClass resources to Karpenter EC2NodeClass, updates NodePool references, adds cluster-name values, and changes FIPS verification to detect the Karpenter CRD.

AWS Load Balancer Controller and platform integration

Layer / File(s) Summary
AWS Load Balancer Controller module
terraform/modules/aws-load-balancer-controller/*, terraform/config/regional-cluster/main.tf
Adds IAM policy, Pod Identity association, Terraform inputs/outputs, chart deployment, and hardened Helm values.
TargetGroupBinding migration
argocd/config/**/templates/*targetgroupbinding.yaml, terraform/modules/*/README.md, terraform/modules/*/alb.tf
Changes TargetGroupBinding resources and examples to elbv2.k8s.aws/v1alpha1 and updates related target-type documentation.
Scheduling and Argo CD drift handling
argocd/config/shared/argocd/*, argocd/config/*/monitoring/*, config/templates/*, deploy/**/applicationset.yaml
Adds CriticalAddonsOnly tolerations, disables selected Prometheus webhook TLS behavior, and ignores controller-managed webhook, Secret, and TargetGroupBinding fields.

Validation and documentation

Layer / File(s) Summary
CI and configuration validation
ci/*, scripts/buildspec/*, terraform/config/*
Adds regional infrastructure validation and DNS diagnostics, changes E2E monitoring execution, extends retry and timeout windows, and preserves merged defaults configuration.
Design and module documentation
docs/design/*, docs/README.md, terraform/modules/*/README.md
Documents OSS Karpenter architecture, bootstrap sequencing, IAM wiring, and the AWS Load Balancer Controller module.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related PRs

Suggested labels: needs-ok-to-test

Suggested reviewers: typeid

✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Fix failing CI checks
🧪 Generate unit tests (beta)
  • Create PR with unit tests

@openshift-ci

openshift-ci Bot commented Jul 30, 2026

Copy link
Copy Markdown

@theautoroboto: The following tests failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
ci/prow/terraform-validate 71dec45 link true /test terraform-validate
ci/prow/helm-lint 71dec45 link true /test helm-lint
ci/prow/images 71dec45 link true /test images
ci/prow/unit-tests 71dec45 link true /test unit-tests
ci/prow/check-docs 71dec45 link true /test check-docs
ci/prow/check-rendered-files 71dec45 link true /test check-rendered-files

Full PR test history. Your PR dashboard.

Details

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. I understand the commands that are listed here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

jira/valid-reference Indicates that this PR references a valid Jira ticket of any type.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants