【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】Amazon DynamoDBを使ってみる(CLI、Part…

  2. AWS

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

  3. AWS

    【AWS】AWS SAMを使いCLIでDynamoDBやLambda関…

  4. AWS

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

  5. AWSのロールプレイングゲーム「AWS Cloud Quest」を触っ…

  6. AWS

    【AWS】AWS Step Functionsを触ってみる

最近の記事

  1. AWS
  2. AWS
  3. AWS

制作実績一覧

  1. Checkeys