Skip to content

[ack_acm_controller] Certificate CR creates new ACM cert instead of using existing one #313

Description

@sanmesh-kakade

Description

The ack_acm_controller module (and downstream nginx_gateway_fabric ingress module) creates a new ACM certificate every time instead of adopting an existing one when an ACM ARN is provided. This leads to duplicate certificates and unnecessary costs.

Affected Modules

  • modules/ack_acm_controller/standard/1.0
  • Downstream: any ingress module that creates ACK Certificate CRs with ACM ARNs (e.g., nginx_gateway_fabric_legacy_aws)

Root Cause

The Certificate CR is created with domainName and exportTo but missing the adoption annotations required to bind to an existing ACM certificate. Without these annotations, the ACK controller calls RequestCertificate to create a new cert.

Fix Required

The Certificate CR needs two annotations to adopt an existing cert instead of creating a new one:

annotations:
  services.k8s.aws/adoption-policy: "adopt"
  services.k8s.aws/adoption-fields: |
    {"arn": "<existing-acm-arn>"}

Additionally, exportTo does not automatically work for adopted certs due to an upstream bug in the ACK ACM controller (reported at aws-controllers-k8s/community#2827). A workaround is needed:

  1. The Kubernetes secret must be pre-created before the Certificate CR
  2. After adoption, status.issuedAt must be cleared to trigger the export:
    kubectl patch certificate.acm.services.k8s.aws <name> \
      --type=json --subresource=status \
      -p '[{"op":"remove","path":"/status/issuedAt"}]'

IAM Policy

The IAM policy must include acm:ExportCertificate for the export to work. The acm:RequestCertificate permission can be removed if only adopting existing certs (least privilege). The current module has been updated with the correct read-only permissions in PR #309.

Full working flow (verified on saas-cp-production)

  1. Create empty Kubernetes secret
  2. Create Certificate CR with adoption annotations + exportTo
  3. Clear status.issuedAt on the Certificate CR (via Job or kubectl patch)
  4. Controller exports cert + private key into the secret

Tasks

  • Add adoption annotations to Certificate CR in ingress modules
  • Add a Kubernetes Job to clear issuedAt after adoption (with retry, timeout, and error propagation)
  • Ensure secret is pre-created before the Certificate CR
  • Update ack_acm_controller module IAM policy (done in PR Restrict ACK ACM controller IAM to read-only #309)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions