Как получить доступ к IP-адресам службы Cloud Run из Terraform / Pulumi для динамического создания записей A? - PullRequest
1 голос
/ 01 марта 2020

Я использую Google Cloud Run с Pulumi (аналог Terraform). Моя настройка для сопоставления доменов Cloud Run:

  new gcp.cloudrun.DomainMapping(
    `${prefix}-domain-mapping`,
    {
      location,
      name: 'xxx',
      metadata: {
        namespace: projectId,
      },
      spec: {
        routeName: appService.name,
      },
    },
    {
      dependsOn: [appService],
    },
  )

Где appService указывает на экземпляр службы Cloud Run. Это успешно создает сопоставление домена со службой Cloud Run.

Далее я настраиваю зону DNS с записями:

  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,
    },
  )

Приведенный выше код работает. У меня есть зона DNS с четырьмя записями A, указывающими на 4 разных IP-адреса, которые указывают на сервис Cloud Run. Моя проблема заключается в следующем: как мне автоматизировать IP-адреса, которые я жестко запрограммировал выше? Я хочу, чтобы IP-адреса Cloud Run были динамически установлены для записей A. Переменная ips должна указывать на IP-адреса экземпляра Cloud Run, но я не могу найти способ сделать это.

Или, возможно, я делаю все это неправильно, и есть другой способ, которым это должно быть сделано ? Моя цель - чтобы служба Cloud Run обновлялась и получала новые IP-адреса, а также автоматически обновлялись записи DNS. Я не хочу обновлять адреса вручную.

Поскольку Pulumi более или менее эквивалентен Terraform, ответы в Terraform или Pulumi очень ценятся!

Ответы [ 2 ]

2 голосов
/ 02 марта 2020

Я не пробовал запускать это, но по крайней мере этот код компилируется:

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,
});

Танец с records призван избавиться от undefined на двух уровнях ... Не уверен, что если это может быть упрощено.

1 голос
/ 04 марта 2020

Поскольку этот вопрос помечен тегами Pulumi и Terraform, вот возможное решение Terraform:

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
}
...