🌐

AWS CDKで実装するリダイレクトサーバ

に公開

AWS CDKで実装するリダイレクトサーバ

はじめに

自社プロダクトサイトのURL変更に伴い、リダイレクトサーバをAWS CDKで構築したので、その知見を共有します。

背景

もともと mirumi.ux-xu.com をStudioに独自ドメインを登録して公開していました。
今回、ブランディング戦略に伴い、mirumi.tokyoにドメインを変更することにしました。
旧URL(mirumi.ux-xu.com)にアクセスしても新URL(mirumi.tokyo)にリダイレクトされるように、リダイレクト専用の Web サーバーを構築します。

使用サービス整理

  • ムームーDNS
    • 旧URL mirumi.ux-xu.comのドメイン取得で利用
  • お名前.com
    • 新URL mirumi.tokyoのドメイン取得で利用
  • Studio
    • プロダクトサイトホスティングサービス
    • 独自ドメインでの公開も可能(有料)
  • AWS
    • 自社でメインで使用しているクラウドサービス

技術選定

以下のAWSのサービスを使用してリダイレクトを実現します。

  • Amazon S3:静的ウェブサイトホスティングとリダイレクト設定
  • Amazon CloudFront:CDN配信およびHTTPS対応
  • AWS Certificate Manager (ACM):SSL証明書の管理

インフラはAWS CDKを用いてコードで管理し、再現性の高いデプロイを可能にします。

実装手順

1. ドメインの設定

新ドメインサーバで mirumi.tokyo のAレコードをStudioの指示に従って設定します。
今回はお名前.comを使用したので、それを例に説明します。

  • Studioのマニュアルに基づき 34.111.141.225 を登録
    • Studioの「設定する」ボタンを押すと入力欄が表示され、「追加」で保存します。

ネームサーバーは「お名前.comのネームサーバーを使う」に変更してください。
この設定をしないと、Aレコードにお名前.comのIPアドレスが設定され、正しく遷移できません。

設定確認コマンド:

dig mirumi.tokyo +short

設定したIPアドレスが表示されればOKです。

Studioのコンソールを開き、独自ドメインを新しいドメイン名に変更します。

変更が終わったら、旧ドメインサーバのStudio用のAレコードを削除します。

2. AWS CDKの開発

エントリーポイントは下記のとおりです。
再利用したい場合は、domainsの部分を変更してください。

bin/redirect-server.ts
#!/usr/bin/env node
import * as cdk from 'aws-cdk-lib'
import { CertificateStack } from '../lib/certificate-stack'
import { RedirectStack } from '../lib/redirect-stack'

const app = new cdk.App()
const account = process.env.CDK_DEFAULT_ACCOUNT
const region = 'us-east-1' // cloudfront用にACMを作成するためにはus-east-1を指定する必要あり

const env = { account, region }
const tags = {
  ProjectName: 'redirect-server',
}

const domains = {
  old: 'mirumi.ux-xu.com',
  new: 'mirumi.tokyo',
}

const certStack = new CertificateStack(app, 'redirectCertificateStack', {
  env,
  tags,
  domains,
})

new RedirectStack(app, 'RedirectStack', {
  env,
  tags,
  certificate: certStack.certificate,
  domains,
})

スタック定義は下記の通りです。
証明書のデプロイとCloudFrontのデプロイを分けています。

lib/certificate-stack.ts
import { Stack, StackProps, aws_certificatemanager as acm } from 'aws-cdk-lib'
import { Construct } from 'constructs'
import { Domains } from './types'

export interface CertificateStackProps extends StackProps {
  domains: Domains
}

export class CertificateStack extends Stack {
  public readonly certificate: acm.Certificate

  constructor(scope: Construct, id: string, props: CertificateStackProps) {
    super(scope, id, props)

    this.certificate = new acm.Certificate(this, 'RedirectCertificate', {
      domainName: props.domains.old,
      validation: acm.CertificateValidation.fromDns(),
    })
  }
}
lib/redirect-stack.ts
import {
  Stack,
  StackProps,
  aws_certificatemanager as acm,
  aws_cloudfront as cloudfront,
  aws_cloudfront_origins as origins,
  aws_s3 as s3,
  RemovalPolicy,
  CfnOutput,
} from 'aws-cdk-lib'
import { Construct } from 'constructs'
import { Domains } from './types'

export interface RedirectStackProps extends StackProps {
  certificate: acm.ICertificate
  domains: Domains
}

export class RedirectStack extends Stack {
  constructor(scope: Construct, id: string, props: RedirectStackProps) {
    super(scope, id, props)

    const bucket = new s3.Bucket(this, 'RedirectBucket', {
      bucketName: props.domains.old + '-redirect',
      websiteRedirect: {
        hostName: props.domains.new,
        protocol: s3.RedirectProtocol.HTTPS,
      },
      removalPolicy: RemovalPolicy.DESTROY,
      autoDeleteObjects: true,
    })

    const distribution = new cloudfront.Distribution(this, 'RedirectDistribution', {
      defaultBehavior: {
        origin: new origins.S3StaticWebsiteOrigin(bucket),
        viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
      },
      domainNames: [props.domains.old],
      certificate: props.certificate,
      defaultRootObject: '',
    })

    new CfnOutput(this, 'CloudFrontDomainName', {
      value: distribution.domainName,
    })
  }
}
lib/types.ts
export interface Domains {
  old: string
  new: string
}

3. 証明書のデプロイ・設定

まずはCDKでACM証明書をデプロイします。

cdk deploy --exclusively CertificateStack

AWSコンソールでACMを開き、以下を確認・設定します。

  • CNAME名と値を確認し、旧ドメインのDNSサーバに追加してください。
  • DNS検証が完了すると証明書が有効化されます

4. リダイレクトサーバのデプロイ

CloudFrontとS3を含むリダイレクト構成をデプロイします。

cdk deploy --exclusively RedirectStack

デプロイ後、CloudFrontのディストリビューションのドメイン名を確認し、旧ドメインのCNAMEレコードに設定します。

4. 動作確認

DNS設定が反映されたか確認します。

dig mirumi.ux-xu.com +short
# => CloudFront のドメイン名(例:d23as4dkjuswop.cloudfront.net)

最後にブラウザで mirumi.ux-xu.com にアクセスし、mirumi.tokyo に遷移すれば成功です!

実装のポイント

  • CloudFront で使用する ACM 証明書は us-east-1 リージョンで作成する必要があります。

    • ap-northeast-1 に証明書があるとCloudFrontとの連携に失敗します(ソース)。
  • S3バケットの静的ウェブサイトホスティング機能を使ってリダイレクト先(mirumi.tokyo)を設定

まとめ

旧ドメイン(mirumi.ux-xu.com)から新ドメイン(mirumi.tokyo)へHTTPSリダイレクトが構成できました。
また、AWS CDKを用いて実装することで、再利用しやすい構成としました。

ユカイ工学テックブログ

Discussion