Skip to content

feat(azure): delegate-domain support — create DNS zone, refactor cert flow#2136

Merged
lionello merged 6 commits into
mainfrom
edw/azure-delegate-domain
Jun 2, 2026
Merged

feat(azure): delegate-domain support — create DNS zone, refactor cert flow#2136
lionello merged 6 commits into
mainfrom
edw/azure-delegate-domain

Conversation

@edwardrf
Copy link
Copy Markdown
Contributor

@edwardrf edwardrf commented Jun 1, 2026

What

Implements PrepareDomainDelegation for the Azure provider so each project gets a dedicated public DNS zone in Azure DNS, returning the zone's name servers for Fabric to delegate. Mirrors the GCP provider's approach.

Headline pieces:

  • pkg/clouds/azure/dns — armdns wrapper with EnsureZoneExists (idempotent get-then-create), matching GCP's EnsureDNSZoneExists.
  • pkg/cli/client/byoc/azure/byoc.goPrepareDomainDelegation creates the zone in the per-project-stack resource group (ensuring the RG exists via the existing idempotent CreateResourceGroup), returns the NS records, and stores the zone name for parity with the GCP provider's delegateDomainZone field. HasDelegatedSubdomain returns true so destroy calls fabric.DeleteSubdomainZone. DOMAIN env var is forwarded to the CD task via the cdCommand struct, mirroring the AWS provider's pattern (see pkg/cli/client/byoc/aws/byoc.go).
  • pkg/clouds/azure/aca/cert.go — moves the existing IssueCert flow from pkg/cli/client/byoc/azure/cert.go into the cloud-SDK layer so both the CLI's defang cert generate and the CD task (separate repo) can call it directly without crossing the byoc → cloud-SDK boundary. The *ByocAzure.IssueCert method is now a thin wrapper; pure refactor for the CLI's BYOD path. Each ARM step's idempotency is preserved, and there's an added alreadyServingTLS short-circuit so re-deploys skip the cert dance when nothing changed.
  • pkg/cli/client/byoc/common.go — when DEFANG_PULUMI_DIR runs CD locally, forward AZURE_STORAGE_{KEY,ACCOUNT,SAS_TOKEN} and AZURE_TENANT_ID from the host shell into the subprocess so Pulumi's azblob backend can authenticate directly. Avoids DefaultAzureCredential falling through to AzureCLICredential, which times out under nix's slow az startup. No-op for the ACA-job path, which uses managed identity in-cloud.

Why split this from the pulumi-defang change

The companion pulumi-defang PR adds the per-service CNAME + asuid TXT records (Pulumi-managed) and the CD-side hook that calls aca.IssueCert to register the customDomain + issue ManagedCertificate + bind SniEnabled, completing the delegate-domain flow.

The cd package in pulumi-defang imports aca.IssueCert from this repo, so this PR has to merge first. Until the pulumi-defang side merges, the DOMAIN env var is set but unread, and the new aca package has only its existing in-repo caller. Both are harmless no-ops, and the AWS provider already follows the same shape (DOMAIN set, consumed by the corresponding CD).

Verification

  • Unit tests: cd src && make test — passes including new tests for azuredns.EnsureZoneExists, PrepareDomainDelegation empty-domain / credential-error paths, and HasDelegatedSubdomain.
  • Lint: cd src && make lint — 0 issues.
  • E2E (manual): nextjs sample on azurewestus3, fresh deploy provisions zone → records → cert + binding in ~9 min; HTTPS serves a valid DigiCert-issued cert for app.<delegate-domain> in ~0.6s response time.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Azure BYOC tenants can delegate domains to enable public DNS zone management for custom hostnames.
    • Automated managed-certificate provisioning for Azure Container Apps: DNS validation, certificate issuance, and TLS binding for custom hostnames.
  • Chores

    • Updated Azure SDK dependency and build packaging configuration.

… flow

Implements PrepareDomainDelegation for the Azure provider so each project
gets a dedicated public DNS zone in Azure DNS, returning the zone's name
servers for Fabric to delegate. Mirrors the GCP provider's approach.

Headline pieces:

- pkg/clouds/azure/dns: armdns wrapper with EnsureZoneExists (idempotent
  get-then-create), matching GCP's EnsureDNSZoneExists.

- pkg/cli/client/byoc/azure/byoc.go: PrepareDomainDelegation creates the
  zone in the per-project-stack resource group (ensuring the RG exists
  via the existing idempotent CreateResourceGroup), returns the NS records,
  and stores the zone name for parity with the GCP provider's
  delegateDomainZone field. HasDelegatedSubdomain returns true so destroy
  calls fabric.DeleteSubdomainZone. DOMAIN env var is forwarded to the CD
  task via the cdCommand struct, mirroring the AWS provider's pattern.

- pkg/clouds/azure/aca/cert.go: moves the existing IssueCert flow from
  pkg/cli/client/byoc/azure/cert.go into the cloud-SDK layer so both the
  CLI's `defang cert generate` and the CD task (separate repo) can call
  it directly without crossing the byoc → cloud-SDK boundary. The
  *ByocAzure.IssueCert method is now a thin wrapper. Pure refactor for
  the CLI's BYOD path; idempotency of every ARM step is preserved.

- pkg/cli/client/byoc/common.go: when DEFANG_PULUMI_DIR runs CD locally,
  forward AZURE_STORAGE_{KEY,ACCOUNT,SAS_TOKEN} and AZURE_TENANT_ID from
  the host shell into the subprocess so Pulumi's azblob backend can
  authenticate directly. Avoids DefaultAzureCredential falling through
  to AzureCLICredential, which times out under nix's slow `az` startup.
  No-op for the ACA-job path, which uses managed identity in-cloud.

The companion pulumi-defang change adds the per-service CNAME + asuid TXT
records (Pulumi-managed) and the CD-side hook that calls aca.IssueCert to
register the customDomain + issue ManagedCertificate + bind SniEnabled,
completing the delegate-domain flow.

Verified end-to-end on Azure westus3 with the nextjs sample: fresh deploy
provisions zone → records → cert + binding in ~9 min; HTTPS serves a
valid DigiCert-issued cert for app.<delegate-domain> in ~0.6s response.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 1, 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: 5743194e-b5ed-46aa-9591-ade7f5311d59

📥 Commits

Reviewing files that changed from the base of the PR and between 0db5d59 and b870e85.

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

📝 Walkthrough

Walkthrough

Adds Azure DNS zone management and a shared Container Apps certificate issuance flow; wires delegate-domain through ByocAzure deployment/CD, implements PrepareDomainDelegation to create/ensure delegate zones and return name servers, and refactors ByocAzure.IssueCert to delegate to the new ACA flow.

Changes

Azure DNS Delegation and Certificate Provisioning

Layer / File(s) Summary
Azure DNS Zone Management
src/pkg/clouds/azure/dns/dns.go, src/pkg/clouds/azure/dns/dns_test.go
New DNS type creates or retrieves public Azure DNS zones. EnsureZoneExists returns authoritative name servers; on 404 it creates a public global zone. Tests verify nil-safe name server extraction and credential error propagation.
Container Apps Certificate Provisioning
src/pkg/clouds/azure/aca/cert.go, src/pkg/clouds/azure/aca/cert_test.go
Shared IssueCert orchestrates multi-step managed-certificate flow: find tagged Container App, validate DNS with CNAME + asuid TXT verification, register hostname (Disabled), issue cert with CNAME-then-TXT fallback, rebind with SNI, and poll TLS readiness. Includes ARM-safe naming, idempotency helpers, and hostname binding utilities. Tests verify managed-cert naming invariants and hostname distinction.
BYOC Domain Delegation Implementation
src/pkg/cli/client/byoc/azure/byoc.go, src/pkg/cli/client/byoc/azure/byoc_test.go, src/pkg/cli/client/byoc/baseclient.go, src/go.mod
PrepareDomainDelegation now ensures project resource group, creates/retrieves Azure DNS zone for the delegate domain, and returns name servers; flips HasDelegatedSubdomain() to true. Extends cdCommand with delegate-domain field and wires it through runCdCommand as a DOMAIN environment variable. Tests cover empty-domain and credential-error paths. Documentation comment clarifies delegation scope. Azure DNS SDK dependency added to go.mod.
BYOC Certificate Issuance Refactor
src/pkg/cli/client/byoc/azure/cert.go
Simplifies ByocAzure.IssueCert to a thin adapter: creates Azure credentials, computes resource group name, and delegates full certificate workflow to the new shared aca.IssueCert. Removes 400+ lines of in-file Azure SDK orchestration.
Build Configuration
pkgs/defang/cli.nix
Updates Go module vendorHash for the defang-cli Nix build derivation.

Sequence Diagram(s)

sequenceDiagram
  participant CLI
  participant ByocAzure
  participant DNS
  participant ACA
  participant AzureARM
  CLI->>ByocAzure: PrepareDomainDelegation(domain)
  ByocAzure->>DNS: EnsureZoneExists(domain)
  DNS-->>ByocAzure: Name servers
  ByocAzure->>CLI: return name servers
  CLI->>ByocAzure: deploy with DelegateDomain
  ByocAzure->>ACA: IssueCert(...) (uses DNS resolver)
  ACA->>AzureARM: manage Container App & managed certificate lifecycle
  ACA->>DNS: verify CNAME/TXT during issuance
  ACA->>AzureARM: bind certificate and enable SNI
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • DefangLabs/defang#2087: Touches BYOC Azure CD wiring and CD environment construction overlapping with this PR's deploy/CD env changes.
  • DefangLabs/defang#2106: Changes delegated-subdomain deletion guarded by provider.HasDelegatedSubdomain(); this PR flips HasDelegatedSubdomain() to true and implements PrepareDomainDelegation.
  • DefangLabs/defang#2099: Related Azure BYOC certificate issuance work and integration points around IssueCert.

Suggested reviewers

  • jordanstephens
  • lionello

Poem

🐰 I hopped through DNS and ARM,
spun certificates without alarm,
delegated a domain with care,
bound SNI and polled TLS there,
a rabbit's patch: secure and fair.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 54.84% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main changes: adding domain delegation support for Azure, creating a DNS zone, and refactoring the certificate flow.
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-delegate-domain

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.2)

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.

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: 3

🧹 Nitpick comments (2)
src/pkg/cli/client/byoc/azure/byoc.go (1)

49-51: 💤 Low value

Clarify the purpose of delegateDomainZone field.

This field is assigned at line 755 in PrepareDomainDelegation but never read elsewhere in the file. If it's intended for future cleanup logic (similar to tracking other provisioned resources), consider adding a TODO comment. If it's meant to mirror the GCP provider's state tracking, document that. Otherwise, the field appears unused.

🤖 Prompt for 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.

In `@src/pkg/cli/client/byoc/azure/byoc.go` around lines 49 - 51, The
delegateDomainZone field is assigned in PrepareDomainDelegation but never read;
either remove delegateDomainZone if unused, or document intended purpose by
adding a TODO comment and/or a short doc comment above the field explaining it
mirrors GCP provider state or will be used for cleanup; if intended for future
cleanup, ensure PrepareDomainDelegation and any cleanup method (e.g., the
provider's teardown/Unprepare function) reference delegateDomainZone so it is
actually used for resource tracking.
src/pkg/clouds/azure/dns/dns.go (1)

80-91: ⚡ Quick win

Prefer consistent zero-value return: empty slice over nil.

nameServers() returns nil when zone.Properties is nil (line 82) but returns an empty slice []string{} when NameServers is empty (line 84's make creates a non-nil empty slice). This inconsistency can surprise callers who check result == nil vs len(result) == 0. Return an empty slice in both cases for predictable zero-value semantics.

♻️ Proposed fix
 func nameServers(zone armdns.Zone) []string {
 	if zone.Properties == nil {
-		return nil
+		return []string{}
 	}
 	servers := make([]string, 0, len(zone.Properties.NameServers))
 	for _, ns := range zone.Properties.NameServers {
 		if ns != nil {
 			servers = append(servers, *ns)
 		}
 	}
 	return servers
 }

As per coding guidelines: "Treat zero values intentionally."

🤖 Prompt for 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.

In `@src/pkg/clouds/azure/dns/dns.go` around lines 80 - 91, The nameServers
function returns nil when zone.Properties is nil but returns a non-nil empty
slice when NameServers is empty; make the return value consistent by returning
an empty slice instead of nil whenever there are no name servers. Update
nameServers (and the zone.Properties nil branch) so it always returns a
zero-length []string (e.g., construct servers with make([]string,0) and return
that when zone.Properties is nil or when NameServers yields no entries),
referencing the nameServers function, zone.Properties, and
zone.Properties.NameServers to locate the change.
🤖 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/clouds/azure/aca/cert.go`:
- Around line 175-193: The patch is using the stale `current` value loaded
before the DNS wait, which can drop concurrent domain additions; in
addHostnameDisabled, re-fetch the latest ContainerApp resource (call the
ContainerAppsClient get method to retrieve the up-to-date resource) immediately
before building `domains` and calling `client.BeginUpdate`, then recheck
hasCustomDomain against that fresh resource, recompute
`existingCustomDomains(current)` from the refreshed object, and handle any GET
error before proceeding to BeginUpdate to avoid overwriting newer CustomDomains
entries.
- Around line 443-452: The managedCertName function currently trims env and
hostname which can cause collisions for long hostnames; update managedCertName
to append a short deterministic uniqueness suffix (e.g., 6-char hex or base36
derived from a hash of envName+hostname using sha256/sha1) after the sanitized
host segment so names remain deterministic and unique. Keep the existing
sanitize(), 15-char env and 30-char host truncation logic, then compute the
hash(sanitize(envName)+":"+sanitize(hostname)) and append a hyphen + first N
chars of the hex/base36 digest (N small, e.g., 6) to the returned string from
managedCertName to avoid collisions while preserving current length behavior.
Ensure the suffix is included in the final fmt.Sprintf("mc-%s-%s", ...) result
or appended to it (function managedCertName).

---

Nitpick comments:
In `@src/pkg/cli/client/byoc/azure/byoc.go`:
- Around line 49-51: The delegateDomainZone field is assigned in
PrepareDomainDelegation but never read; either remove delegateDomainZone if
unused, or document intended purpose by adding a TODO comment and/or a short doc
comment above the field explaining it mirrors GCP provider state or will be used
for cleanup; if intended for future cleanup, ensure PrepareDomainDelegation and
any cleanup method (e.g., the provider's teardown/Unprepare function) reference
delegateDomainZone so it is actually used for resource tracking.

In `@src/pkg/clouds/azure/dns/dns.go`:
- Around line 80-91: The nameServers function returns nil when zone.Properties
is nil but returns a non-nil empty slice when NameServers is empty; make the
return value consistent by returning an empty slice instead of nil whenever
there are no name servers. Update nameServers (and the zone.Properties nil
branch) so it always returns a zero-length []string (e.g., construct servers
with make([]string,0) and return that when zone.Properties is nil or when
NameServers yields no entries), referencing the nameServers function,
zone.Properties, and zone.Properties.NameServers to locate the change.
🪄 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: 1231358a-11fd-4ab2-ba5b-8374779b8755

📥 Commits

Reviewing files that changed from the base of the PR and between e496a4a and a5a8554.

⛔ Files ignored due to path filters (1)
  • src/go.sum is excluded by !**/*.sum
📒 Files selected for processing (10)
  • src/go.mod
  • src/pkg/cli/client/byoc/azure/byoc.go
  • src/pkg/cli/client/byoc/azure/byoc_test.go
  • src/pkg/cli/client/byoc/azure/cert.go
  • src/pkg/cli/client/byoc/common.go
  • src/pkg/cli/composeUp.go
  • src/pkg/clouds/azure/aca/cert.go
  • src/pkg/clouds/azure/aca/cert_test.go
  • src/pkg/clouds/azure/dns/dns.go
  • src/pkg/clouds/azure/dns/dns_test.go

Comment thread src/pkg/clouds/azure/aca/cert.go Outdated
Comment thread src/pkg/clouds/azure/aca/cert.go
Comment thread src/pkg/clouds/azure/aca/cert.go Outdated
Four changes responding to coderabbit's review on PR #2136:

1. addHostnameDisabled: refetch the ContainerApp right before the merge-patch
   instead of reusing the snapshot the caller fetched before the DNS wait.
   waitForBYODdns can block for up to 30 min, and ARM uses JSON Merge Patch
   that replaces the customDomains array wholesale — a stale slice would
   silently drop concurrent additions from another deploy. Drops the now-
   redundant *ContainerApp parameter; updates the IssueCert call site.

2. submitManagedCertTXT: stop swallowing every client.Get failure during
   the validation-token polling loop. Only the expected 404 (token not yet
   issued) should be retried. Permission, auth, and transient provider
   errors are now wrapped and returned instead of being dragged out to a
   generic 5-minute timeout — matches the project's error-handling rule.

3. managedCertName: append a short sha256 hash of the lowercased hostname
   so two long hostnames sharing the same first 21 sanitized characters
   no longer collide on the same managed-cert resource within an env
   (where the second issuance would overwrite the first). sha256 (not
   sha1) to satisfy gosec G505/G401; we only take 4 bytes, so output
   length is similar. Tests describe the contract by recomputing the
   suffix locally; one new test guards the collision case explicitly.

4. nameServers: return []string{} consistently instead of nil when
   zone.Properties is missing, so callers that check `== nil` and callers
   that check `len() == 0` see the same shape.

Also expanded the comment on ByocAzure.delegateDomainZone explaining it
mirrors the GCP provider's same-named field — set on success, currently
informational only, kept as a hook for a future explicit-cleanup path.

All affected packages still pass `go test -short` and `make lint`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@edwardrf
Copy link
Copy Markdown
Contributor Author

edwardrf commented Jun 1, 2026

Pushed 7ab3384d addressing the 5 review comments:

Comment Resolution
cert.go:193 — refetch CustomDomains before PATCH Done. addHostnameDisabled now does its own Get immediately before the merge-patch and drops the stale-snapshot parameter.
cert.go:345 — return non-404 Get errors from token poll Done. submitManagedCertTXT now distinguishes 404 (retry) from other ARM errors (wrap+return) via azcore.ResponseError.
cert.go:452 — uniqueness suffix on managedCertName Done. Appends sha256(lower(hostname))[:4] as hex; tests recompute the suffix locally so they describe the contract. Added a regression test for the collision case. Used sha256 instead of the suggested sha1 to satisfy gosec G505/G401 — we only use 4 bytes either way, so name length is comparable.
byoc.go:49 — clarify delegateDomainZone purpose Done. Expanded the comment to call out the GCP parity and that it's informational/cleanup-hook only today (matches the GCP provider, which uses the same field with the same usage).
dns.go:80 — consistent zero-value return Done. nameServers now returns []string{} in both branches.

go build ./..., go test -short ./..., and make lint (gosec included) all clean. The companion pulumi-defang PR will be opened after this lands.

The separate flaky-test fix went out as #2137.

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/pkg/clouds/azure/aca/cert_test.go (1)

156-219: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Stale comment: suffix uses sha256, not "sha1".

Line 171 documents the appended suffix as "sha1", but expectedSuffix (and per the PR, managedCertName) derives it from sha256. The mismatched algorithm name is misleading, especially since sha256 was specifically chosen here for gosec.

✏️ Proposed comment fix
 		// want is the prefix-plus-truncated-segments portion of the name;
-		// the per-hostname sha1 suffix is appended automatically.
+		// the per-hostname sha256 suffix is appended automatically.
 		want string
🤖 Prompt for 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.

In `@src/pkg/clouds/azure/aca/cert_test.go` around lines 156 - 219, The test
comment incorrectly says the appended per-hostname suffix is "sha1" while the
code (expectedSuffix and managedCertName) uses SHA-256; update the comment to
say "sha256" (or a neutral phrasing like "per-hostname hash using sha256") so it
matches the implementation, and ensure any surrounding text referencing "sha1"
is corrected to "sha256" to avoid confusion when reviewing managedCertName and
expectedSuffix.
🤖 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/clouds/azure/aca/cert_test.go`:
- Around line 234-244: The test doc comment incorrectly refers to a "sha1
suffix" even though the cert name suffix is derived from sha256; update the
comment on TestManagedCertName_DistinguishesLongHostnames to say
"sha256-derived" (or simply "hash-derived") to match the implementation in
managedCertName and avoid misleading references.

---

Outside diff comments:
In `@src/pkg/clouds/azure/aca/cert_test.go`:
- Around line 156-219: The test comment incorrectly says the appended
per-hostname suffix is "sha1" while the code (expectedSuffix and
managedCertName) uses SHA-256; update the comment to say "sha256" (or a neutral
phrasing like "per-hostname hash using sha256") so it matches the
implementation, and ensure any surrounding text referencing "sha1" is corrected
to "sha256" to avoid confusion when reviewing managedCertName and
expectedSuffix.
🪄 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: 9a1d1bef-ff6f-4f8a-871c-e00cdae8c04d

📥 Commits

Reviewing files that changed from the base of the PR and between a5a8554 and 7ab3384.

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

Comment thread src/pkg/clouds/azure/aca/cert_test.go
Copy link
Copy Markdown
Member

@jordanstephens jordanstephens left a comment

Choose a reason for hiding this comment

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

The PR description mentions a companion pulumi-defang PR, but it's not clear which PR that is referring to. Can we clarify?

Comment thread src/pkg/cli/client/byoc/azure/byoc.go
Comment thread src/pkg/cli/client/byoc/azure/byoc.go
@edwardrf
Copy link
Copy Markdown
Contributor Author

edwardrf commented Jun 1, 2026

The PR description mentions a companion pulumi-defang PR, but it's not clear which PR that is referring to. Can we clarify?

That PR has dependency on this PR as the related cert gen functions used by both byod cert gen in cli and pulumi-defang for delegate domain is imported by pulumi-defang.

@edwardrf edwardrf requested a review from jordanstephens June 1, 2026 23:34
Comment thread src/pkg/cli/client/byoc/azure/byoc.go Outdated
Comment thread src/pkg/cli/client/byoc/baseclient.go
Comment thread src/pkg/clouds/azure/dns/dns.go
@lionello lionello merged commit 3dfee36 into main Jun 2, 2026
5 checks passed
@lionello lionello deleted the edw/azure-delegate-domain branch June 2, 2026 15:14
@edwardrf edwardrf linked an issue Jun 2, 2026 that may be closed by this pull request
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.

Azure: hook up .defang.app delegated domain

4 participants