Skip to content

Implement azure byod cert gen#2099

Open
edwardrf wants to merge 6 commits intomainfrom
edw/azure-cert-gen
Open

Implement azure byod cert gen#2099
edwardrf wants to merge 6 commits intomainfrom
edw/azure-cert-gen

Conversation

@edwardrf
Copy link
Copy Markdown
Contributor

@edwardrf edwardrf commented May 7, 2026

Description

Implement azure byod cert gen

Linked Issues

DefangLabs/pulumi-defang#216

Checklist

  • I have performed a self-review of my code
  • I have added appropriate tests
  • I have updated the Defang CLI docs and/or README to reflect my changes, if necessary

Summary by CodeRabbit

  • New Features

    • Azure BYOC services can automatically obtain and bind managed TLS certificates for custom domains (CNAME and TXT validation with TLS readiness checks).
    • Added DNS TXT lookup utilities to improve validation checks.
  • Bug Fixes

    • Certificate issuance now surfaces failures instead of masking them.
  • Tests

    • Added unit tests covering certificate issuance, domain/validation detection, and helper utilities.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 7, 2026

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 6a3ee076-242b-43d7-9130-2170a7b72a89

📥 Commits

Reviewing files that changed from the base of the PR and between ffbafa9 and a229b9f.

📒 Files selected for processing (1)
  • src/pkg/cli/cert.go

📝 Walkthrough

Walkthrough

This PR enables Azure Container Apps to issue and bind TLS certificates directly via Azure managed-certificate ARM APIs. It introduces a CertIssuer interface that allows providers to handle certificate issuance, integrates provider-driven routing in GenerateLetsEncryptCert, adds DNS TXT lookup support, and implements the full Azure BYOC certificate orchestration flow including DNS validation, managed certificate provisioning with CNAME/TXT fallback, and TLS verification.

Changes

Azure BYOC Certificate Issuance

Layer / File(s) Summary
DNS Lookup Helpers
src/pkg/dns/check.go
Exports LookupTXT and LookupTXTContains functions to query TXT records and verify expected values via the package resolver.
Certificate Issuer Interface
src/pkg/cli/cert.go
Defines CertIssuer interface with IssueCert method signature for providers that can directly issue and bind certificates.
Certificate Generation Integration
src/pkg/cli/cert.go
GenerateLetsEncryptCert type-asserts provider to CertIssuer; when available and UseAcmeCert is set, derives domain list and calls issuer.IssueCert per hostname; otherwise falls back to original CNAME-based generateCert path and returns joined issuance errors.
Azure Service Configuration
src/pkg/cli/client/byoc/azure/byoc.go
ByocAzure.UpdateServiceInfo sets si.UseAcmeCert = true when the Compose service defines a domainname.
Azure Certificate Issuance Implementation
src/pkg/cli/client/byoc/azure/cert.go
Implements IssueCert orchestrating container app lookup, DNS readiness (CNAME + asuid TXT), idempotent hostname registration, managed certificate creation with CNAME-first and TXT-fallback validation, certificate binding with SniEnabled, and TLS verification. Includes helpers for ARM Container App discovery, DNS polling, validation-method error detection, certificate naming with sanitization, and TLS readiness checks.
Unit Tests
src/pkg/cli/client/byoc/azure/cert_test.go
Tests for custom domain detection with nil safety, InvalidValidationMethod error classification, hostname sanitization, managed certificate resource naming with truncation rules, and string dereferencing utilities.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested reviewers:

  • lionello
  • jordanstephens

A rabbit hops through DNS replies,
CNAMEs point true and TXT records sigh,
Azure crafts a cert with a careful paw,
Binds SNI gently, watches TLS fly,
Little hops of code make secure homes sprout. 🐰✨

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 61.90% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'Implement azure byod cert gen' is vague and uses abbreviated terminology that may not be immediately clear to reviewers scanning commit history. Use clearer terminology: consider 'Implement Azure BYOC managed certificate generation' or 'Add Azure Container Apps certificate issuance support' to improve clarity and expand common abbreviations.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch edw/azure-cert-gen

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (2.12.1)

level=warning msg="The linter 'gomodguard' is deprecated (since v2.12.0) due to: new major version. Replaced by gomodguard_v2."
level=warning msg="Suggested new configuration:\nlinters:\n enable:\n - gomodguard_v2\n"
level=warning msg="[linters_context] running gomodguard failed: unable to read module file go.mod: current working directory must have a go.mod file: if you are not using go modules it is suggested to disable this linter"
level=error msg="[linters_context] typechecking error: pattern ./...: directory prefix . does not contain main module or its selected dependencies"


Comment @coderabbitai help to get the list of available commands and usage tips.

@edwardrf edwardrf changed the title Edw/azure cert gen Implement azure byod cert gen May 7, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/pkg/cli/cert.go`:
- Around line 117-124: GenerateLetsEncryptCert currently logs issuer.IssueCert
errors via term.Errorf but always returns nil, so callers can't detect failures;
change GenerateLetsEncryptCert to collect errors from each issuer.IssueCert call
(e.g., append to a slice or use an error-aggregator) and after the loop return a
consolidated non-nil error when any IssueCert failed (or wrap multiple errors
with fmt.Errorf/%w or a multierror), preserving the existing term.Errorf logging
but propagating the error out of GenerateLetsEncryptCert so callers can react to
issuance failures.

In `@src/pkg/cli/client/byoc/azure/cert.go`:
- Around line 353-362: The managedCertName function can produce a trailing
hyphen when you do sanitize() then slice (env[:15]/host[:30]); fix by ensuring
you remove any trailing hyphens after truncation. Specifically, in
managedCertName sanitize envName and hostname, then apply the length limits,
then trim any leading or trailing hyphens from the truncated strings (and handle
the case of an empty result by providing a fallback like "env" or "host");
update the code around the managedCertName function to perform the
post-truncation hyphen trim so the returned fmt.Sprintf("mc-%s-%s", env, host)
never contains consecutive hyphens.
- Around line 157-182: The PATCH body in addHostnameDisabled and
bindHostnameSniEnabled replaces the entire CustomDomains array, which drops
existing registrations; instead, ensure you preserve and update the
current.ContainerApp.Properties.Configuration.Ingress.CustomDomains: in
addHostnameDisabled use the provided current to prepend/append the new
armappcontainers.CustomDomain (checking hasCustomDomain first) to
current.Properties.Configuration.Ingress.CustomDomains and pass that full array
in the BeginUpdate body; in bindHostnameSniEnabled, fetch the current app if not
provided, locate and update the matching CustomDomain entry in
current.Properties.Configuration.Ingress.CustomDomains (set
SniEnabled/CertificateId/etc.) or append if missing, then call BeginUpdate with
the complete modified CustomDomains array so other domains are not overwritten.

In `@src/pkg/dns/check.go`:
- Around line 94-101: The function LookupTXTContains currently logs with
term.Debugf which bypasses the injectable package Logger; update the logging
call inside LookupTXTContains to use the package-level Logger (Logger.Debugf) so
tests can override or silence logs, keeping the existing message and arguments
(name, txts, err) and leaving the rest of the function unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 4977f295-93cb-462d-9bfb-098206156d2c

📥 Commits

Reviewing files that changed from the base of the PR and between 7902437 and 2adf5a0.

📒 Files selected for processing (8)
  • src/pkg/cli/cert.go
  • src/pkg/cli/cert_test.go
  • src/pkg/cli/client/byoc/aws/domain_test.go
  • src/pkg/cli/client/byoc/azure/byoc.go
  • src/pkg/cli/client/byoc/azure/cert.go
  • src/pkg/dns/check.go
  • src/pkg/dns/mock.go
  • src/pkg/dns/resolver.go

Comment thread src/pkg/cli/cert.go
Comment thread src/pkg/cli/client/byoc/azure/cert.go
Comment thread src/pkg/cli/client/byoc/azure/cert.go
Comment thread src/pkg/dns/check.go
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/pkg/cli/cert.go`:
- Line 140: The current return returns errors.Join(issueErrs...) which exposes
raw errors without remediation; update the caller in the cert issuance function
(where issueErrs is assembled and returned) to wrap the joined error with a
user-facing message that includes clear remediation steps (e.g., "failed to
issue certificate: <joined errors>; try checking X, Y, or run `command`") by
constructing a new error (using fmt.Errorf or errors.Join+fmt.Errorf) that
prefixes a short actionable instruction and includes the joined issueErrs for
diagnostics; ensure the change references the issueErrs variable and the
function that returns it so logs and callers receive the wrapped, actionable
error.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 683b0d06-05ff-4fee-ab90-f5542b64a54a

📥 Commits

Reviewing files that changed from the base of the PR and between 765a9b8 and ffbafa9.

📒 Files selected for processing (4)
  • src/pkg/cli/cert.go
  • src/pkg/cli/client/byoc/azure/cert.go
  • src/pkg/cli/client/byoc/azure/cert_test.go
  • src/pkg/dns/check.go
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/pkg/cli/client/byoc/azure/cert_test.go
  • src/pkg/cli/client/byoc/azure/cert.go

Comment thread src/pkg/cli/cert.go Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants