【AWS】Github ActionsやAWS SAMを使ってAWS S3・CloudFrontにウェブコンテンツをデプロイし、サブドメインにアクセスできるようにする

AWS

1. 概要

前回はNextJSアプリをServerlessのLambdaにデプロイする内容でした。今回はS3+Cloudfrontにウェブコンテンツをデプロイし、サブドメインにアクセスする内容となります。

  • 概要図

  • ディレクトリ構造
.
├── .github
│   └── workflows
│       └── deploy.yaml
├── .gitignore
├── README.md
├── samconfig.toml
├── static
│   ├── 404.html
│   ├── README.md
│   └── index.html
└── template.yaml

3 directories, 8 files

2. Nodeのインストール

こちらを参考

3. AWSアカウントにサインアップ

3-1. 前提条件

4. AWSアクセスキーの取得

4-1. AWSアクセスキーの取得

5. AWS CLI のインストール

5-1. インストール

6. AWS SAM CLIのインストール

6-1. インストール

7. GitHub ActionsのSecretsを設定

7-1. こちらを参考

8. プロジェクトを作成

8-1. こちらを参考

  • ただのディレクトリを1つ作成
    • serverless-s3-demo

9. ウェブコンテンツを作成

9-1. static/index.html

<html lang="ja">
<head>
  <title>Hello</title>
</head>
<body>
  <h1>Happy coding!</p>
</body>
</html>

9-2. static/404.html

<html lang="ja">
<head>
  <title>404</title>
</head>
<body>
  <h1>File not found</p>
</body>
</html>

10. template.yamlを作成

10-1. template.yaml

AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::Serverless-2016-10-31
Description: Serverless web application with s3

Parameters:
  BucketName:
    Type: String
  DomainName:
    Type: String
  SubDomainName:
    Type: String
  HostedZoneId:
    Type: String
  AcmCertificateArn:
    Type: String
  IndexDocument:
    Type: String
    Default: "index.html"
  ErrorDocument:
    Type: String
    Default: "404.html"

Resources:
  S3WebBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Ref BucketName
      AccessControl: Private
      PublicAccessBlockConfiguration:
        BlockPublicAcls: true
        BlockPublicPolicy: true
        IgnorePublicAcls: true
        RestrictPublicBuckets: true
      WebsiteConfiguration:
        IndexDocument: !Ref IndexDocument
        ErrorDocument: !Ref ErrorDocument

  OriginAccessIdentity:
    Type: AWS::CloudFront::CloudFrontOriginAccessIdentity
    Properties:
      CloudFrontOriginAccessIdentityConfig:
        Comment: !Ref AWS::StackName

  S3WebBucketPolicy:
    Type: AWS::S3::BucketPolicy
    Properties:
      Bucket: !Ref S3WebBucket
      PolicyDocument:
        Id: "PolicyForCloudFrontPrivateContent"
        Statement:
          - Sid: "AllowCloudFrontServicePrincipal"
            Effect: "Allow"
            Action: "s3:GetObject"
            Resource: !Sub "arn:aws:s3:::${S3WebBucket}/*"
            Principal:
              Service: "cloudfront.amazonaws.com"
            Condition:
              StringEquals:
                {
                  "AWS:SourceArn": !Sub "arn:aws:cloudfront::${AWS::AccountId}:distribution/${CloudFrontDistribution.Id}",
                }

  CloudFrontOAC:
    Type: AWS::CloudFront::OriginAccessControl
    Properties:
      OriginAccessControlConfig:
        Name: !Sub "${AWS::StackName}-OAC"
        Description: "OAC for CloudFront to access S3"
        OriginAccessControlOriginType: "s3"
        SigningBehavior: "always"
        SigningProtocol: "sigv4"

  CloudFrontDistribution:
    Type: AWS::CloudFront::Distribution
    Properties:
      DistributionConfig:
        Aliases:
          - !Sub "${SubDomainName}.${DomainName}"
        ViewerCertificate:
          AcmCertificateArn: !Ref AcmCertificateArn
          MinimumProtocolVersion: TLSv1.2_2021
          SslSupportMethod: sni-only
        Enabled: true
        HttpVersion: http2
        Comment: !Ref AWS::StackName
        DefaultRootObject: !Ref IndexDocument
        Origins:
          - Id: s3BucketOrigin
            DomainName: !GetAtt S3WebBucket.RegionalDomainName
            S3OriginConfig:
              OriginAccessIdentity: ""
            OriginAccessControlId: !Ref CloudFrontOAC
        DefaultCacheBehavior:
          TargetOriginId: s3BucketOrigin
          ViewerProtocolPolicy: redirect-to-https
          Compress: "true"
          AllowedMethods:
            - GET
            - HEAD
            - OPTIONS
          ForwardedValues:
            QueryString: "false"
            Cookies:
              Forward: none
          MinTTL: 0
          DefaultTTL: 86400
          MaxTTL: 31536000

  Route53RecordSetA:
    Type: AWS::Route53::RecordSet
    DependsOn: CloudFrontDistribution
    Properties:
      HostedZoneName: !Sub "${DomainName}."
      Name: !Sub "${SubDomainName}.${DomainName}."
      Type: A
      AliasTarget:
        HostedZoneId: !Ref HostedZoneId
        DNSName: !GetAtt CloudFrontDistribution.DomainName

Outputs:
  SubDomainUrl:
    Description: ""
    Value: !Sub "https://${Route53RecordSetA}"

10-2. samconfig.toml

version = 0.1
[default.deploy.parameters]
stack_name = "serverless-s3-demo"
resolve_s3 = true
s3_prefix = "serverless-s3-demo"
region = "ap-northeast-1"
capabilities = "CAPABILITY_IAM"
image_repositories = []
parameter_overrides = [
  "BucketName=serverless-s3-demo",
  "DomainName=hoge.com",
  "SubDomainName=xyz",
  "HostedZoneId=Z2FDTNDATAQYW2",
  "AcmCertificateArn=arn:aws:acm:us-east-1:123456789012:certificate/12345678-9012-3456-7890-123456789012",
  "IndexDocument=index.html",
  "ErrorDocument=404.html",
]

11. githubのworkflowsファイルを作成

11-1. .github/workflows/deploy.yaml

name: Deploy Web app to S3
on:
  push:
    branches:
      - main
  workflow_dispatch:
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v2
      - name: Set up AWS Credentials
        uses: aws-actions/configure-aws-credentials@v2
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: ap-northeast-1
      - name: SAM build
        run: sam build --template-file template.yaml
      - name: SAM deploy
        run: sam deploy --template-file template.yaml --no-confirm-changeset --no-fail-on-empty-changeset
      - name: Deploy to S3
        run: aws s3 sync static s3://serverless-s3-demo --delete --exclude "README.md"

12. アプリケーションをAWS クラウドにデプロイ

12-1. deploy

「main」ブランチにpush OR mergeすると自動的に実行(デプロイ)される

git push origin main
  • SAM deploy
.
.
.
CloudFormation outputs from deployed stack
------------------------------------------------------------------------------------------------------------------------------------------------------------
Outputs                                                                                                                                                    
------------------------------------------------------------------------------------------------------------------------------------------------------------
Key                 SubDomainUrl                                                                                                                           
Description                                                                                                                                                
Value               https://xyz.hoge.com                                                                                                            
------------------------------------------------------------------------------------------------------------------------------------------------------------


Successfully created/updated stack - serverless-s3-demo in ap-northeast-1

13. アプリケーションを確認

13-1. サブドメインを取得

  • 上記14-1ログより「Outputs」を探す
    • Key
      • SubDomainUrl
    • Value
      • https://xyz.hoge.com
      • これがサブドメイン

13-2. 画面で確認

14. Management Consoleで確認

14-1. 画面で確認

  • Route 53

15. AWSクラウドからアプリケーションを削除

※必要に応じ削除

sam delete --stack-name serverless-s3-demo
  • 「S3バケット」にファイルが存在してる場合は自動削除されないため、S3のみ手動で削除

16. 備考

今回はS3+Cloudfrontにウェブコンテンツをデプロイし、サブドメインにアクセスする内容でした。

17. 参考

  1. AWS Serverless Application Model (AWS SAM) とは何ですか? – AWS Serverless Application Model (amazon.com)
  2. GitHub Actions ドキュメント – GitHub Docs
  3. A SAM template that describe an Amazon CloudFront distribution that serve a static website from an S3 Bucket. · GitHub

投稿者プロフィール

Sondon
開発好きなシステムエンジニアです。
卓球にハマってます。

関連記事

  1. AWS

    【AWS】Redash on EC2 が突然 502 Bad Gate…

  2. AWS

    【AWS】APIGatewayのバックアップ、復元

  3. AWS

    【AWS】API Gatewayを使ってみる

  4. AWS

    【AWS】DynamoDBのバックアップ、復元、別リージョンへのコピー…

  5. 【新米エンジニア学習記録④】Next.jsのデプロイⅡ

  6. AWS

    【API Gateway】Lambda Web AdapterからWe…

最近の記事

  1. Node.js
  2. AWS

制作実績一覧

  1. Checkeys