Hi again folks :smile: I'm at the tail end of a mu...
# getting-started
m
Hi again folks 😄 I'm at the tail end of a multi-account/environment/stack setup with a TLD and multiple subdomains. We're using one stack + AWS account per environment for isolation. Need a sanity check please, from both a Pulumi and a holistic networking perspective. In the shared account/stack (this is not an environment, just shared resources): • Imported the Route53 TLD zone provided by AWS. • Added a policy that all environments/accounts/stacks can assume. ◦ Attached a role that only allows necessary Route53 actions. In each environment's account/stack: • Create a provider that assumes an IAM role with proper permissions in the shared account/stack. • Import the shared TLD zone ( as a aws.route53.Zone object) using the provider. • If the environment account/stack is production, we add an alias record pointing the imported TLD zone to its' ALB and we're done! ◦ Question: When adding an "A" record to the shared account for prod from the prod account/stack, should I be using the provider or doing it from that stack's context? • If the is not production, in its' account/stack we: ◦ Create a Route 53 zone for the subdomain. ▪︎ Add an "A"/alias record to it, pointing the zone to that environment/stack's ALB. ◦ Insert an NS record into the shared account's TLD zone with the subdomain's name and the subdomain zone's NS records using the shared account's provider. Code for all of this is in the reply to this since it's a bit long and I don't want to spam the channel. Thank you in advance 🙏
Shared account pulumi code:
Copy code
const rootZone = new aws.route53.Zone(tldName, {
    name: tldName,
	comment: 'HostedZone created by Route53 Registrar'
}, {
	import: tldZoneId
});

const allowedTargetArns = [
	rootZone.arn
]

const allowedActions = [
	"route53:ChangeResourceRecordSets",
	"route53:CreateHostedZone",
	"route53:DeleteHostedZone",
	"route53:GetChange",
	"route53:GetHostedZone",
	"route53:ListHostedZones",
	"route53:ListResourceRecordSets",
	"route53:UpdateHostedZoneComment"
]

const allowedSourceArns = adminStack.getOutput('crossAccountPermissionPolicyTargets');

const crossAccountAccessRole = new aws.iam.Role(pre('cross-acct-role'), {
    assumeRolePolicy: allowedSourceArns.apply(sourceArns => { 
		return JSON.stringify({
        Version: "2012-10-17",
        Statement: [{
            Effect: "Allow",
            Principal: {
                AWS: sourceArns
            },
            Action: "sts:AssumeRole"
        }]
    })
})});

const crossAccountAccessPolicy = new aws.iam.Policy(pre('cross-acct-policy'), {
	policy: pulumi.all(allowedTargetArns).apply(targetArns => {
		return JSON.stringify({
			"Version": "2012-10-17",
			"Statement": [
				{
					"Effect": "Allow",
					"Action": allowedActions,
					"Resource": targetArns
				}
			]
		})
	})
});

const policyAttachment = new aws.iam.RolePolicyAttachment(pre('cross-acct-attach'), {
    role: crossAccountAccessRole.name,
    policyArn: crossAccountAccessPolicy.arn
});
Each environment account's stack:
Copy code
const rootZone = new aws.route53.Zone(pre('dns-zone'), {
    name: tldName,
	comment: 'HostedZone created by Route53 Registrar'
}, rootZoneArn.apply(zoneArn => {
	return { import: zoneArn, provider: sharedAccountProvider }
}) as unknown as { import: string, provider: aws.Provider });

if (!subDomainName) { // If it's the TLD, add an A record to our ALB and we're done!
	const aliasRecord = new aws.route53.Record(pre('dns-alias'), {
		name: tldName, // Replace with your domain/subdomain
		type: "A",
		zoneId: rootZone.id,
		aliases: [{
			name: applicationLoadBalancer.loadBalancer.dnsName,
			zoneId: applicationLoadBalancer.loadBalancer.zoneId,
			evaluateTargetHealth: true,
		}],
	}, );
} else {
	const subDomainZone = new aws.route53.Zone(pre('dns-zone'), {
		name: `${subDomainName}.${tldName}`
	});
	const aliasRecord = new aws.route53.Record(pre('alias-record'), {
		name: `${subDomainName}.${tldName}`,
		type: "A",
		ttl: 60,
		zoneId: subDomainZone.id,
		aliases: [{
			name: applicationLoadBalancer.loadBalancer.dnsName,
			zoneId: applicationLoadBalancer.loadBalancer.zoneId,
			evaluateTargetHealth: true,
		}],
	});
	const nsRecord = new aws.route53.Record(pre('dns-record'), {
		zoneId: rootZone.id,
		name: `${subDomainName}.${tldName}`,
		type: "NS",
		ttl: 86400,
		records: subDomainZone.nameServers,
	}, {
		provider: sharedAccountProvider
	})
}