I am using Google Cloud Run with Pulumi (similar to Terraform). My setup for Cloud Run's domain mapping is:
new gcp.cloudrun.DomainMapping(
`${prefix}-domain-mapping`,
{
location,
name: 'xxx',
metadata: {
namespace: projectId,
},
spec: {
routeName: appService.name,
},
},
{
dependsOn: [appService],
},
)
Where appService points to an instance of Cloud Run service. This successfully creates a domain mapping to the Cloud Run service.
Next I am setting up a DNS zone with records:
const zone = new gcp.dns.ManagedZone(`${prefix}-zone`, {
name: `${prefix}-zone`,
dnsName: 'xxx.',
visibility: 'public',
})
const ips = ['xxx', 'xxx', 'xxx', 'xxx']
new gcp.dns.RecordSet(
`${prefix}-a-records`,
{
name: 'xxx.',
managedZone: zone.name,
type: 'A',
ttl: 3600,
rrdatas: ips,
},
{
dependsOn: [zone],
deleteBeforeReplace: true,
},
)
The code above works. I have a DNS zone with four A records pointing to 4 different IP-addresses, which point to a Cloud Run service. My problem is this: how do I automate the IPs, which I have hard-coded above? I want the IP-addresses of Cloud Run to be dynamically set for the A records. The ips variable has to point to the Cloud Run instance's IPs, but I can't find a way to do that.
Or perhaps I'm doing this all wrong and there's another way this should be done? My goal is that if the Cloud Run service is updated and receives new IPs, the DNS records should be automatically updated as well. I don't want to manually update addresses.
Since Pulumi is more or less equivalent to Terraform, answers in either Terraform or Pulumi are greatly appreciated!
Since this question is tagged with both Pulumi and Terraform tags, here's a possible Terraform solution:
resource "google_cloud_run_domain_mapping" "example" {
location = "us-central1"
name = "xxx"
metadata {
namespace = local.project_name
}
spec {
route_name = google_cloud_run_service.app.name
}
}
resource "google_dns_managed_zone" "example" {
name = "${local.prefix}-zone"
dns_name = "xxx."
visibility = "public"
}
locals {
dns_records = {
"A" = [
for rr in google_cloud_run_domain_mapping.example.resource_records :
rr.rrdata if rr.type == "A"
]
"AAAA" = [
for rr in google_cloud_run_domain_mapping.example.resource_records :
rr.rrdata if rr.type == "AAAA"
]
}
}
resource "google_dns_record_set" "example" {
for_each = local.dns_records
managed_zone = google_dns_managed_zone.example.name
name = "xxx."
type = each.key
ttl = 3600
rrdatas = each.value
}
I haven't tried running this but at least this code compiles:
const mapping = new gcp.cloudrun.DomainMapping(...);
const records = mapping.status.resourceRecords?.apply(rs => rs ?? []) ?? pulumi.output([]);
new gcp.dns.RecordSet(`${prefix}-a-records`, {
name: 'xxx.',
managedZone: zone.name,
type: 'A',
ttl: 3600,
rrdatas: records.apply(rs => rs.map(r => r.rrdata)),
}, {
dependsOn: [zone, mapping],
deleteBeforeReplace: true,
});
The dance with records is there to get rid of undefined on two levels... Not sure if it can be simplified.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With