AWS CDK: как настроить таргетинг API шлюза API из Route53

У меня есть существующее доменное имя, зарегистрированное в AWS Route53, и я настроил собственное доменное имя в API Gateway. В консоли я могу настроить такие вещи, как xxxxxx.zenxxxxxxfoundry.com извне, на самом деле достигает API-интерфейса шлюза API, а затем переходит к моим функциям Lambda.

Теперь я хочу добиться этого с помощью AWS CDK.

Я пробовал следующее:

    const zone = route53.HostedZone.fromHostedZoneId(this, 'ZenithWebFoundryZone', 'ZXXXXXX04V8134');
    new route53.AliasRecord(this, 'BlogAPIRecord', {
      zone: zone,
      recordName: 'xxxxxx.zenxxxxxxfoundry.com',
      target: {
        bind: (): route53.AliasRecordTargetProps => ({
          dnsName: 'd-xxxxxxy00g.execute-api.ap-southeast-2.amazonaws.com',
          hostedZoneId: 'ZXXXXXX04V8134'
        })
      }
    });

который строится нормально npm run build но когда я запускаю cdk synth я получаю довольно тупую ошибку:

$ cdk synth
HostedZone.fromHostedZoneId doesn't support "zoneName"
Subprocess exited with error 1

Включение --trace особо не помогло: дополнительная информация:

Error: Subprocess exited with error 1
    at ChildProcess.proc.on.code (/Users/mikecoxon/.npm-packages/lib/node_modules/aws-cdk/lib/api/cxapp/exec.ts:108:23)
    at ChildProcess.emit (events.js:189:13)
    at ChildProcess.EventEmitter.emit (domain.js:441:20)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:248:12)

Я просмотрел весь скрипт стека, и нигде нет ссылки на zoneName. Кто-нибудь знает, откуда эта ошибка?

ZenithWebFoundryZone — это имя зоны, которое вы передаете методом fromHostedZoneId? В документации сказано, что вторым параметром fromHostedZoneId является id, но не объясняется идентификатор чего.
Chetan 13.06.2019 04:04

Нет, это на самом деле третий параметр. «id» кажется всегда вторым параметром для этих фабричных методов, и большинство примеров, кажется, представляют это как своего рода дескриптор создаваемой конструкции. Однако в большинстве примеров дескриптор фактически не используется, поэтому я предполагаю, что он имеет какое-то применение в результирующем шаблоне формирования облака.

Michael Coxon 13.06.2019 04:30

Я сослался на эту документацию docs.aws.amazon.com/cdk/api/latest/docs/…, и она от AWS.... в соответствии с тем, что третий параметр — hostedZoneId.... но нет объяснения параметра id.

Chetan 13.06.2019 05:01
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
12
3
9 807
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

Я получил ту же ошибку со следующим:

const zone = route53.HostedZone.fromHostedZoneId(this, 'MyZone', 'ZXXXXXXXXXXXXX');

У меня есть зона в Route53, похожая на приведенную ниже:

Domain Name:    example.com.
Type:           Public Hosted Zone
Hosted Zone ID: ZXXXXXXXXXXXXX

Я изменил на следующее, и это сработало (CDK 0.34.0):

const zone = new route53.HostedZoneProvider(this,  {
  domainName: 'example.com',
}).findAndImport(this, 'MyZone');

Я думал об этом, я просто боялся попробовать, потому что думал, что это может повредить мою текущую зону хостинга, которая настроена и работает. Может, мне закрыть глаза и попробовать?

Michael Coxon 14.06.2019 12:32
Ответ принят как подходящий

С aws-cdk v1 должна быть возможность делать следующее:

const zone = route53.HostedZone.fromHostedZoneAttributes(this, 'ZenithWebFoundryZone', {
  hostedZoneId: 'ZXXXXXX04V8134',
  zoneName: 'zenxxxxxxfoundry.com' // your zone name here
});

new route53.ARecord(this, 'BlogAPIRecord', {
  zone,
  recordName: 'xxxxxx.zenxxxxxxfoundry.com',
  target: route53.RecordTarget.fromAlias({
    bind() {
      return {
        dnsName: 'd-xxxxxxy00g.execute-api.ap-southeast-2.amazonaws.com', // Specify the applicable domain name for your API.,
        hostedZoneId: 'XXXX', // Specify the hosted zone ID for your API.
      };
    },
  }),
});

Если ваш API находится в том же стеке/базе кода, вы можете получить от него dnsName и hostedZoneId (это атрибут CF).

В противном случае обратитесь к DNSName и HostedZoneId в Документация AWS::Route53::RecordSet AliasTarget.

Примечание: hostedZoneId для записи вашего псевдонима нет совпадает с идентификатором размещенной зоны вашей собственной зоны.

Я готов подтвердить ваше предложение, однако, похоже, я сейчас заморочился с этим вопросом и не могу выполнить cdk synth на данный момент.

Michael Coxon 15.06.2019 06:25

подтвердил, что это работает - большое спасибо. У меня было много проблем с чистым обновлением до 0.34.0 через npm.

Michael Coxon 19.06.2019 00:18

Я вижу AddressRecordTarget устаревшим в моем редакторе. Я пока не знаю, чем его заменить - я обновлю здесь, если смогу.

halfer 12.03.2021 22:14

@halfer используйте RecordTarget, обновил ответ.

jogold 14.03.2021 11:17

Мила, спасибо за редактирование. У меня может быть другая проблема, прежде чем я доберусь до этого — я хочу создать HostedZone в CDK, где мне нужно делегировать DNS другой учетной записи AWS. Вы случайно не знаете, как взять на себя роль, настроенную в удаленной учетной записи, не так ли? Все примеры, которые я нахожу, — это использование ролей для выполнения каких-либо действий в развернутых объектах, а не роли для самого развертывания.

halfer 14.03.2021 11:24

В AWS CDK 0.36.1 вы можете использовать пакет @aws-cdk/aws-route53-targets для создания псевдонимов.

import { HostedZone, RecordSet, RecordType, RecordTarget } from '@aws-cdk/aws-route53'
import { ApiGatewayDomain } from '@aws-cdk/aws-route53-targets'
import { Certificate } from '@aws-cdk/aws-certificatemanager'

// ...

  const customDomain = new apigateway.DomainName(this, 'CustomDomain', {
    domainName: props.apiDomain,
    certificate: Certificate.fromCertificateArn(this, 'Certificate', props.certificateArn),
    endpointType: apigateway.EndpointType.EDGE,
  })

  const hostedZone = HostedZone.fromHostedZoneAttributes(this, 'HostedZone', {
    hostedZoneId: props.hostedZoneId,
    zoneName: props.hostedZoneName,
  })

  new RecordSet(this, 'ApiRecordSetA', {
    zone: hostedZone,
    recordType: RecordType.A,
    recordName: 'api',
    target: RecordTarget.fromAlias(new ApiGatewayDomain(customDomain))
  })

  new RecordSet(this, 'ApiRecordSetAAAA', {
    zone: hostedZone,
    recordType: RecordType.AAAA,
    recordName: 'api',
    target: RecordTarget.fromAlias(new ApiGatewayDomain(customDomain))
  })

Мне удалось заставить это работать, но я был пойман с именем размещенной зоны, требующим «.». в конце этого.

Это для СУЩЕСТВУЮЩИХ размещенных зон, которые были созданы вручную и которые необходимо искать для добавления записей псевдонимов через CDK.

const hostedZone = route53.HostedZone.fromHostedZoneAttributes(this, 'HostedZone', {
  hostedZoneId: config.apiHostedZoneId,
  name: `${config.apiDomainName}.`,
});

new route53.RecordSet(this, 'ApiRecordSetA', {
  zone: hostedZone,
  recordType: route53.RecordType.A,
  recordName: config.apiDomainName,
  target: route53.RecordTarget.fromAlias(new route53Targets.ApiGatewayDomain(apiDomain))
});

new route53.RecordSet(this, 'ApiRecordSetAAAA', {
  zone: hostedZone,
  recordType: route53.RecordType.AAAA,
  recordName: config.apiDomainName,
  target: route53.RecordTarget.fromAlias(new route53Targets.ApiGatewayDomain(apiDomain))
});

Я столкнулся с той же проблемой, используя cdk 1.36.1, и мне удалось решить ее, используя новое имя пользовательского домена в ApiGateway вместе с сопоставлением BasePath, а затем добавив запись CName в существующую размещенную зону на route53, указывающую на новый личный домен:

import {BasePathMapping, DomainName, EndpointType, LambdaRestApi} from '@aws-cdk/aws-apigateway';
import {Certificate} from '@aws-cdk/aws-certificatemanager';
import {HostedZone, CnameRecord} from '@aws-cdk/aws-route53'

// First create a custom domain:
const customDomain = new DomainName(this, 'customDomain', {
      domainName: 'api.xxxxxxx.com',
      certificate: Certificate.fromCertificateArn(this, 'ACM_Certificate', ACM_CERTIFICATE_ARN),
      endpointType: EndpointType.EDGE
});

// create a new ApiGateway instance and associate a lambda function with it:
const api = new LambdaRestApi(this, 'MainGatewayEndpoint', {
      handler: toyFunction,
});

// Associate the Custom domain that we created with new APIGateway using BasePathMapping:
new BasePathMapping(this, 'CustomBasePathMapping', {
      domainName: custom,
      restApi: api
});

// Get a reference to AN EXISTING hosted zone using the HOSTED_ZONE_ID. You can get this from route53
const hostedZone = HostedZone.fromHostedZoneAttributes(this, 'HostedZone', {
      hostedZoneId: PROD_HOSTED_ZONE_ID,
      zoneName: 'xxxxxxx.com'
});

// Finally, add a CName record in the hosted zone with a value of the new custom domain that was created above:
new CnameRecord(this, 'ApiGatewayRecordSet', {
      zone: hostedZone,
      recordName: 'api',
      domainName: customDomain.domainNameAliasDomainName
});

В документации для размещенных зон — в частности, методы fromHostedZoneID и fromHostedZoneAttributes:

https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-route53.HostedZone.html#static-fromwbrhostedwbrzonewbrattributesscope-id-attrs

в нем особо упоминается, что «имя размещенной зоны становится недоступным через этот запрос»

объект HostedZone, возвращаемый fromHostedZoneID, не имеет атрибута для zoneName и поэтому не может использоваться с route53.AliasRecord — вы должны использовать fromHostedZoneAttributes. чтобы получить информацию, устанавливающую запись A, необходимую для cdk.

Обратите внимание: если вы назначаете домен в объявлении своего API, используйте (в python, потому что это то, что у меня есть, извините)

route53.ARecord(
        self, "DomainAliasLogicalID",
        zone=route53_host_zone,
        target=route53.RecordTarget.from_alias(route53_targets.ApiGateway(your_api_object)),
        record_name=your_domain_name
    )

Если вы настраиваете свой собственный объект доменного имени (не являющийся частью шлюза API, используйте route53_targets.ApiGatewayDomain(your_domain_object)

Другие вопросы по теме