여러 하위 도메인을 동일한 전면으로 가리키기

32074 단어 serverlessuxawscdk

This article was first published on bahr.dev.
Signup for the mailing list and get new articles straight to your inbox!


일찍이 2019년에 나는 스포츠 클럽을 위해 온라인 티켓 상점을 세웠다.이 상점의 핵심은 지불을 처리하고 전자메일로 PDF를 보낼 수 있는 인터넷 응용 프로그램이다.맞춤형으로 말하자면 일이 매우 까다롭게 변한다. 클럽마다 서로 다른 이름, 서로 다른 사진, 때로는 그들이 고객에게 서로 다른 질문을 하려고 한다.모든 클럽에 맞춤형 체험을 제공하기 위해서 우리는 모든 클럽에 자신의 자역을 제공했다.최종적으로 여섯 가지 다른 전단 배치, 여러 개의 지점, 코드 라이브러리가 분화되기 시작한다.최근에 DNS 레코드를 사용하여 도메인 아래의 모든 요청 라우트를 동일한 프런트엔드로 라우팅할 수 있다는 사실을 알게 되었습니다.다행히도
본고는 AWS Cloud Development Kit (CDK)을 사용하여 DNS 기록과 정적 사이트를 만들고 여러 개의 하위 영역을 같은 전단에 배치하는 방법을 설명한다.이것은 모든 고객에게 맞춤형 체험을 제공할 수 있을 뿐만 아니라 하나의 전단 배치도 제공할 수 있습니다.

단축키: 인프라 즉 코드(IaC)가 필요하지 않으면 노선 53의 기록 *.yourdomain.com이 기존의 Cloud Front 버전을 가리키는 것과 같은 결과를 얻을 수 있습니다.
신기한 점은'통합부 루트'장에 있다.Check out the full source code on GitHub .

선결 조건


본고의 해결 방안을 배치하려면 AWS 계정과 AWS CDK을 사용한 경험을 가지고 있어야 합니다.Amazon Route 53에 사용되지 않는 도메인을 등록하는 것도 좋지만, 다른 공급업체와 이미 사용된 도메인을 사용하는 방법을 배울 것입니다.
이 문서에서는 CDK 버전 1.60.0을 사용합니다.업데이트 버전에 문제가 있으면 알려주세요!cdk bootstrap을 실행하여 CDK 계정을 부트하십시오.DnsValidatedCertificate에 사용할 것이 필요합니다.
옵션: Understanding how DNS and especially nameservers work은 잠재적인 라우팅 문제를 해결하는 데 도움이 됩니다.

솔루션


고객의 관점에서 해결 방안을 찾겠습니다.고객으로서 저는 bear.picture.bahr.dev 또는 forest.picture.bahr.dev 또는 *.picture.bahr.dev 형식의 다른 주소로 이동하여 단어의 그림을 처음에 보고 싶습니다.개발자로서 나는 가능한 한 복잡성을 줄이고 싶다.다중 프런트엔드 배포는 복잡성을 증가시킵니다.
요청 흐름은 다음과 같습니다.

위에서 보실 수 있습니다. 도메인만 바뀌었고 다른 것은 아무것도 없습니다.해결 방안의 핵심은 모든 하위 영역의 유량을 특정 목표에 연결할 수 있도록 하는 어댑터 기록이다.그리고 웹 사이트에서 URL을 가져와 하위 영역을 추출하고 정확한 그림을 요청할 수 있습니다.다음 장에서 우리는 각 부분을 상세하게 소개할 것이다.

1. 관리 영역 만들기


AWS에 DNS 레코드를 등록하려면 create a Hosted Zone in Route 53이 필요합니다.Each Hosted Zone costs $0.50 per month .
라우팅 53으로 관리되는 도메인이 있고 다른 용도로 사용되지 않으면 관리 영역이 가장 쉽게 설정됩니다.
Route 53 도메인을 다른 목적(예: 블로그)에 이미 사용하거나 Route 53과 다른 공급업체가 관리하는 경우 관리 영역을 설정하는 방법도 검토합니다.
누가 당신의 도메인 이름 (예를 들어 Route 53이나 GoDaddy) 을 관리하느냐에 따라 apex 도메인을 다른 사이트에 사용하고 있다면 해결 방안을 약간 조정해야 합니다.나의 예시에서 나는 이미 나의 apex역 bahr.dev을 나의 블로그에 사용하고 이 역을 GoDaddy가 관리하도록 했다.우리는 다음 장에서 어떻게 정확한 기록을 지정하는지 볼 것이다.
경고: 위탁 관리 구역을 삭제하기 전에 루트 위탁 관리 구역이나 제3자 제공 프로그램의 모든 관련 기록을 삭제하십시오.CNAME 및 NS 레코드는 allow an attacker to serve content in your name이 될 수 있습니다.

1.1. 라우팅 53으로 관리되는 새 도메인


이것은 가장 간단한 방법이다.우리가 필요로 하는 것은 단지 우리의 도메인 이름을 위해 위탁 관리 구역을 세우는 것이다.
import { HostedZone } from '@aws-cdk/aws-route53';

...
const domain = `bahr.dev`;

const hostedZone = new HostedZone(this, "HostedZone", {
    zoneName: domain
});
라우팅 53은 이제 도메인에 DNS 레코드를 제공할 수 있습니다.

1.2. 라우팅 53에서 관리되는 사용 중인 도메인


이것은 apex역에 위탁 관리 구역을 설정했다고 가정합니다. apex역을 다른 내용에 사용하고 하위 구역으로 바꾸기를 원합니다.apex 필드는 최고급 필드입니다. 예를 들어 bahr.dev 또는 google.com입니다.
우리는 DNS 서버에 하위 도메인에 대한 정보를 다른 위탁 관리 구역에 알려주고 ZoneDelegationRecord을 만들어 이를 실현해야 한다.
import { HostedZone } from '@aws-cdk/aws-route53';

...

// bahr.dev is already in use, so we'll start 
// at the subdomain picture.bahr.dev
const apexDomain = 'bahr.dev';
const domain = `picture.${apexDomain}`;

// as above we create a hostedzone for the subdomain
const hostedZone = new HostedZone(this, "HostedZone", {
    zoneName: domain
});
// add a ZoneDelegationRecord so that requests for *.picture.bahr.dev 
// and picture.bahr.dev are handled by our newly created HostedZone
const nameServers: string[] = hostedZone.hostedZoneNameServers!;    
const rootZone = HostedZone.fromLookup(this, 'Zone', { 
  domainName: apexDomain 
});
new ZoneDelegationRecord(this, "Delegation", {
    recordName: domain,
    nameServers,
    zone: rootZone,
    ttl: Duration.minutes(1)
});
낮은 생존 시간(TTL)은 DNS 캐시 만료가 더 빠르기 때문에 더 빠른 시도와 오류를 허용합니다.너는 생산을 준비할 때 이것을 늘려야 한다.
나중에 picture.bahr.dev*.picture.bahr.dev으로 보내는 요청이 같은 CloudFront 배포에 들어갈 수 있도록 기록을 추가할 것입니다.bahr.dev은 영향을 받지 않을 것이다.

1.3. 도메인은 AWS 이외의 공급업체에서 관리


라우팅 53에서 다시 관리 영역을 만들지만 이번에는 DNS 공급업체에 관리 영역의 이름 서버를 수동으로 등록해야 합니다.먼저 AWS 콘솔을 통해 관리 영역을 만듭니다.

이것은 두 개의 이름 서버(NS)와 인증 시작(SOA) 항목을 포함하는 관리 영역을 제공합니다.우리는 권위 있는 이름 서버를 복제하고 DNS 공급업체가 AWS의 위탁 관리 영역에 요청을 할 것이라고 알려 줍니다.

SOA 레코드에서 권위 있는 이름 서버를 복사하여 DNS 공급업체로 이동하여 이름 서버 레코드를 만들고 NameValue의 값을 대체합니다.
Type: NS
Name: picture
Value: ns-1332.awsdns-38.org
picture 같은 하위 도메인에서 시작하려면 *.picture.bahr.dev 같은 특정 값을 사용하고, @ 같은 정점 도메인을 사용하려면 *.bahr.dev을 사용하십시오.

그리고 다음 CDK 코드 세그먼트를 사용하여 수동으로 생성된 관리 영역을 가져옵니다.
import { HostedZone } from '@aws-cdk/aws-route53';

...

const domain = `picture.bahr.dev`;

const hostedZone = HostedZone.fromLookup(this, 'HostedZone', { 
  domainName: domain 
});

2. 인증서


이제 DNS 라우팅이 설정되어 인증서를 요청하고 검증할 수 있습니다.우리는 이 인증서를 사용하여 우리 사이트에 https 서비스를 제공해야 한다.
CDK를 사용하면 하나의 명령에서 인증서를 만들고 검증할 수 있습니다.
import { DnsValidatedCertificate, ValidationMethod } from "@aws-cdk/aws-certificatemanager";

...

const certificate = new DnsValidatedCertificate(this, "Certificate", {
    region: 'us-east-1',
    hostedZone: hostedZone,
    domainName: this.domain,
    subjectAlternativeNames: [`*.${this.domain}`],
    validationDomains: {
        [this.domain]: this.domain,
        [`*.${this.domain}`]: this.domain
    },
    validationMethod: ValidationMethod.DNS,
});
이곳에서 많은 일이 발생했으니, 우리 그것을 분해합시다.
우선, 우리는 us-east-1으로 구역을 설정합니다. 왜냐하면 CloudFront requires certificates to be in us-east-1 이기 때문입니다.
그리고 우리는 CDK 구조 DnsValidatedCertificate을 사용하여 인증서 요청과 lambda 함수를 생성하고 루트 53에 CNAME 기록을 등록합니다.이 기록은 우리가 이 영역을 실제로 가지고 있는지 검증하는 데 쓰인다.
매개 변수 hostedZone은 인증서가 어떤 위탁 관리 구역과 연결되어야 하는지를 지정합니다.이것은 우리가 이전에 창설한 위탁 관리 구역이다.domainNamesubjectAlternativeNames은 인증서가 어떤 영역에 유효해야 하는지를 지정합니다.나머지 매개변수는 검증 프로세스를 구성합니다.

3, 프런트엔드 배포


인증서가 있으면 S3와 CloudFront를 통해 단일 페이지 응용 프로그램(SPA) 배치를 만들 수 있습니다.우리는 npm 패키지 cdk-spa-deploy을 사용하여 S3 버킷을 설정하고 CloudFront 버전을 연결하는 데 필요한 코드량을 줄이고 있습니다.
import { SPADeploy } from 'cdk-spa-deploy';

...

const deployment = new SPADeploy(this, 'spaDeployment')
    .createSiteWithCloudfront({
        indexDoc: 'index.html', 
        websiteFolder: './website', 
        certificateARN: certificate.certificateArn, 
        cfAliases: [this.domain, `*.${this.domain}`]
    });
index.html<p>Hello world!</p>까지 짧은 HTML 파일일 수 있으며 폴더 ./website에 저장해야 합니다.
브라우저에서 자바스크립트를 사용하여 하위 도메인을 가져올 수 있습니다.아래 코드 줄은 URL ice.picture.bahr.dev을 하나의 그룹 ['ice', 'picture', 'bahr', 'dev']으로 나누어 첫 번째 요소 'ice'을 선택합니다.
const subdomain = window.location.host.split('.')[0];
이러한 정보가 있으면 사이트는 CMS에 연락하여 고객에게 적합한 자산을 얻을 수 있습니다.

4. 와일드카드 라우팅


마지막으로 어댑터 루트를 진행할 때가 되었다.아래 CDK 코드를 사용하여 *.picture.bahr.devpicture.bahr.dev으로 전송된 모든 요청은 위에서 설정한 전단에 라우팅됩니다.
import { CloudFrontTarget } from "@aws-cdk/aws-route53-targets";
import { ARecord, RecordTarget } from '@aws-cdk/aws-route53';

...

const cloudfrontTarget = RecordTarget.fromAlias(new CloudFrontTarget(deployment.distribution));

new ARecord(this, "ARecord", {
    zone: hostedZone,
    recordName: `${this.domain}`,
    target: cloudfrontTarget
});

new ARecord(this, "WildCardARecord", {
    zone: hostedZone,
    recordName: `*.${this.domain}`,
    target: cloudfrontTarget
});
일단 모든 DNS 기록이 전파되면 우리는 우리의 설정을 테스트할 수 있다.전체 솔루션을 배포하는 데 10 ~ 15분이 소요될 수 있습니다.

너 혼자 해봐.


다음은 전체 CDK 코드입니다. 기존 CDK 코드 라이브러리에 복사할 수 있습니다.
나는 당신에게 start with checking out the source code을 건의하고 당신의 필요에 따라 도메인과 위탁 관리 구역을 조정할 것을 건의합니다.필요한 경우 ZoneDelegationRecord을 추가합니다.만약 아직 이렇게 하지 않았다면, cdk bootstrap을 실행해야 합니다.
import * as cdk from '@aws-cdk/core';
import { SPADeploy } from 'cdk-spa-deploy';
import { DnsValidatedCertificate, ValidationMethod } from "@aws-cdk/aws-certificatemanager";
import { CloudFrontTarget } from "@aws-cdk/aws-route53-targets";
import { HostedZone, ARecord, RecordTarget } from '@aws-cdk/aws-route53';

export class WildcardSubdomainsStack extends cdk.Stack {

  private readonly domain: string;

  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const domain = `picture.bahr.dev`;

    const hostedZone = new HostedZone(this, "HostedZone", {
      zoneName: domain
    });

    const certificate = new DnsValidatedCertificate(this, "Certificate", {
      hostedZone,
      domainName: this.domain,
      subjectAlternativeNames: [`*.${this.domain}`],
      validationDomains: {
        [this.domain]: this.domain,
        [`*.${this.domain}`]: this.domain
      },
      validationMethod: ValidationMethod.DNS
    });

    const deployment = new SPADeploy(this, 'spaDeployment')
        .createSiteWithCloudfront({
            indexDoc: 'index.html', 
            websiteFolder: './website', 
            certificateARN: certificate.certificateArn, 
            cfAliases: [this.domain, `*.${this.domain}`]
        });

    const cloudfrontTarget = RecordTarget
        .fromAlias(new CloudFrontTarget(deployment.distribution));

    new ARecord(this, "ARecord", {
      zone: hostedZone,
      recordName: `${this.domain}`,
      target: cloudfrontTarget
    });

    new ARecord(this, "WildCardARecord", {
      zone: hostedZone,
      recordName: `*.${this.domain}`,
      target: cloudfrontTarget
    });
  }
}
현재 AWS_PROFILE=myProfile npm run deploy을 실행하여 솔루션을 배포합니다.myProfile을 AWS에서 사용하는 모든 구성 파일로 대체합니다.Here's more about AWS profiles .
배포에 10 ~ 15분이 소요될 수 있습니다.커피 한 잔 마시고 CDK한테 자기 일을 시키세요.문제가 발생하면 아래의 문제 해결 부분을 보십시오.
배치가 완료되면 지정한 도메인의 하위 도메인 (예: bear.picture.bahr.dev은 도메인 picture.bahr.dev) 에 액세스하여 웹 사이트를 볼 수 있어야 합니다.

문제 해결


The DNS routing doesn't work.


DNS 로깅이 오래 지속되면 변경 사항을 테스트하기 어려울 수 있습니다.TTL을 최소화합니다.
도메인이 라우팅 53으로 관리되지 않는 경우 DNS 공급업체의 DNS 라우팅이 제대로 설정되어 있는지 확인합니다.
apex역을 다른 용도로 사용하려면 ZoneDelegationRecord을 설정하고 하위 영역의 유량을 새로운 위탁 관리 영역으로 바꾸십시오.

The deployment failed to clean up.


배치에 실패한 절차에 따라 모든 자원을 정리할 수 있는 것은 아니다.이것은 아마도 DnsValidatedCertificate의 lambda 함수로 만들어진 CNAME 기록 때문일 것이다.관리 영역으로 이동하여 CNAME 레코드를 제거하고 cdk destroy을 실행하거나 AWS 콘솔의 CloudFormation 서비스를 통해 스택을 제거합니다.

Failed to create resource. Cannot read property 'Name' of undefined


창고를 정리하고 제거하고 재배치합니다.나는 이 오류가 어디에서 왔는지 확실하지 않지만, 다시 나를 위해 그것을 복구해 보았다.

The certificate validation times out.


필요한 CNAME 레코드가 DNS 서버에 표시되도록 올바른 방법을 사용하십시오.이전에 도메인 이름을 사용한 적이 있다면 올바른 ZoneDelegationRecord을 설정하십시오.이것은 좀 까다로울 수 있으니 안심하세요.

다음 단계


Check out the full source code, 직접 해보세요!만약 네가 기부를 하고 싶다면, cdk patterns에 홍보 전화를 하는 것이 좋은 생각일 것이다.

한층 더 읽다

  • What is DNS?
  • Host a static website with CloudFront and S3
  • AWS profiles
  • cdk-spa-deploy on GitHub
  • 좋은 웹페이지 즐겨찾기