Skip to content

feat(dns): Route53 hosted zone in another AWS account via a cross-account role (Part of #273, closes #468) - #469

Open
bhumi46 wants to merge 1 commit into
mosip:GH-issue-273-v2from
bhumi46:273-v2/31-cross-account-dns
Open

bhumi46 wants to merge 1 commit into
mosip:GH-issue-273-v2from
bhumi46:273-v2/31-cross-account-dns

Conversation

@bhumi46

@bhumi46 bhumi46 commented Oct 15, 2026

Copy link
Copy Markdown
Member

Part of #273
Closes #468

Problem

A team whose AWS account has no hosted zone for the domain can create every resource except DNS — the zone (e.g. mosip.net) lives in another AWS account. The dns component, the certbot IAM policy and the TLS DNS-01 step all assumed the zone is in the same account.

How it works

The DNS account creates one role, limited to the zone, that trusts the team account's CI user and certbot role. At run time AWS STS hands out temporary (1 h) credentials for it — no keys from the DNS account are shared; the DNS account can revoke access by changing the role; CloudTrail logs both sides.

# profiles/<profile>/aws/common.tfvars — opt-in; unset = zone in this account (unchanged)
dns_role_arn = "arn:aws:iam::<DNS-ACCOUNT-ID>:role/mosip-dns-<team>"
Part With dns_role_arn
dns component records via new aws.dns provider with assume_role (optional dns_role_external_id); nginx lookup stays in the team account
iam component certbot policy = only sts:AssumeRole on the role (name/description unchanged)
TLS DNS-01 (Ansible) generate.py maps dns_role_arn → dns01_route53_role_arn; nginx /root/.aws/config (0600): role_arn + credential_source = Ec2InstanceMetadata → certbot assumes the role, renewals too
Validation ARN format in Terraform and Ansible; role + dns01_credentials_file together rejected

README: new section Domain in another AWS account with the DNS account's trust + permission policies (zone-scoped: ChangeResourceRecordSets, ListResourceRecordSets, GetHostedZone on the zone; GetChange; ListHostedZones/ListHostedZonesByName), the team-side sts:AssumeRole, enable/disable steps.

Tests

  • terraform test: iam 8 (+2: policy only assumes the role, name/description unchanged; bad ARN rejected; the legacy-permissions test still passes = default unchanged), dns root 6 (+2: same records planned via aws.dns; bad ARN rejected), all other suites unchanged; validate all roots; fmt.
  • Real account, read-only terraform plan of the dns root: without dns_role_arn → plans as today; with a non-existent role → Error: Cannot assume IAM Role … STS: AssumeRole … AccessDenied (proves the records go through the role).
  • generate.py: 18 passed (+2: mapping; absent by default). site.yml --syntax-check all profiles.
  • tls block on the mock Ubuntu nginx VM: valid ARN → /root/.aws/config with role_arn/credential_source, dir 0700 / file 0600, root-owned; bad ARN → fails; role + credentials file → fails; unset → skipped, no file.
  • Not run live: needs a second AWS account with the role (certificate issuance cross-account).

🤖 Generated with Claude Code

…ount role (mosip#468)

For a team whose AWS account has no hosted zone for the domain (e.g.
mosip.net is in another account). Opt-in dns_role_arn in common.tfvars:
a role in the DNS account, limited to the zone, trusting the team's CI
user and certbot role. Unset = unchanged behaviour.

- dns: records go through a new aws.dns provider that assumes the role
  (dynamic assume_role, optional dns_role_external_id); the nginx lookup
  stays on the team-account provider.
- iam: with route53_role_arn the certbot policy only allows
  sts:AssumeRole on that role (name/description unchanged; default
  policy byte-for-byte as before).
- Ansible: generate.py maps dns_role_arn -> dns01_route53_role_arn; the
  tls role writes /root/.aws/config (0600) so certbot's route53 plugin
  assumes the role from the instance profile, renewals included. ARN
  validated in Terraform and Ansible.
- Docs: profile comments; README section with the DNS account's trust
  and permission policies, team-side sts:AssumeRole, enable/disable.

Part of mosip#273. Closes mosip#468.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: bhumi46 <thisisbn46@gmail.com>
@coderabbitai

coderabbitai Bot commented Oct 15, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

🗂️ Base branches to auto review: 17
  • ^main$
  • ^master$
  • ^master-java21$
  • ^develop$
  • ^develop2$
  • ^develop/.*
  • ^release$
  • ^release/.*
  • ^release-.*
  • ^\d+.\d+.x$
  • ^\d+.\d+.\d+$
  • ^hotfix/.*
  • ^hotfix-.*
  • ^issue-.*
  • develop
  • release-*
  • MOSIP*

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration
  • Configuration used: Repository UI
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 6ffb6126-f771-4b91-8e8d-a115369ed19b

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

This branch has not been deployed

No deployments
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.

1 participant