LoginSignup
0
0

More than 1 year has passed since last update.

AWS CloudFormationでS3にSPA(React)を構築しよう

Posted at

はじめに

AWS CloudFormationを利用してS3静的ホスティング・SPA(React)構築のテンプレートのサンプルです。

テンプレートの概要が分からない場合は、はじめてのAWS CloudFormationテンプレートを理解するを参考にしてください。

コードはGitHubにもあります。

今回は、akane というシステムの dev 環境を想定しています。
同じ構成で違う環境を作成する場合は、{環境名}-parameters.jsonを別途作成します。

ディレクトリ構成
akane (システム)
  ├── app (Reactアプリ)
  └── s3 (スタック)
      ├─ s3.yml (CFnテンプレート)
      └─ dev-parameters.json (dev 環境のパラメータ)

AWS リソース構築内容

  1. s3スタック
    • s3バケット (akane-dev-s3-reacts)
    • バケットポリシー (s3:GetObject)

実行環境の準備

AWS CloudFormationを動かすためのAWS CLIの設定を参考にしてください。

Reactアプリ ビルド手順

  1. 予め node.js yarn をインストールする。

  2. 下記を実行してアプリをビルドする

    cd akane/app
    
    yarn install
    
    yarn build
    

AWS リソース構築手順

  1. 下記を実行してスタックを作成

    ./create_stacks.sh
    
  2. 下記を実行してスタックを削除

    ./delete_stacks.sh
    

構築テンプレート

1. s3スタック

s3.yml
AWSTemplateFormatVersion: 2010-09-09
Description: S3 For Akane

# Metadata:

Parameters:
  SystemName:
    Type: String
    AllowedPattern: '[a-zA-Z0-9-]*'
  EnvType:
    Description: Environment type.
    Type: String
    AllowedValues: [all, dev, stg, prod]
    ConstraintDescription: must specify all, dev, stg, or prod.
  AppS3Bucket:
    Type: String
  AppIndexDocument:
    Type: String

# Mappings

# Conditions

# Transform

Resources:
  # S3 Bucket作成
  akaneS3Bucket:
    Type: AWS::S3::Bucket
    Properties:
      AccessControl: Private
      BucketName: !Ref AppS3Bucket
      Tags:
        - Key: Name
          Value: !Ref AppS3Bucket
        - Key: SystemName
          Value: !Ref SystemName
        - Key: EnvType
          Value: !Ref EnvType
      WebsiteConfiguration:
        IndexDocument: !Ref AppIndexDocument
  # S3 BucketPolicy作成
  akaneS3BucketPolicy:
    Type: AWS::S3::BucketPolicy
    DependsOn: akaneS3Bucket
    Properties:
      Bucket: !Ref akaneS3Bucket
      PolicyDocument:
        Statement:
          - Action:
              - s3:GetObject
            Effect: Allow
            Resource: !Join
              - ''
              - - 'arn:aws:s3:::'
                - !Ref akaneS3Bucket
                - /*
            Principal:
              AWS: '*'

Outputs:
  akaneS3Bucket:
    Value: !Ref akaneS3Bucket
    Export:
      Name: !Ref AppS3Bucket

all-parameters.json
{
    "Parameters": [
        {
            "ParameterKey": "SystemName",
            "ParameterValue": "akane"
        },
        {
            "ParameterKey": "EnvType",
            "ParameterValue": "dev"
        },
        {
            "ParameterKey": "AppS3Bucket",
            "ParameterValue": "akane-dev-s3-react"
        },
        {
            "ParameterKey": "AppIndexDocument",
            "ParameterValue": "index.html"
        }
    ]
}

3. 実行ファイル

create_stacks.sh
#!/bin/sh

cd `dirname $0`

SYSTEM_NAME=akane

create_stack () {
    ENV_TYPE=$1
    STACK_NAME=$2
    aws cloudformation create-stack \
    --stack-name ${SYSTEM_NAME}-${ENV_TYPE}-${STACK_NAME} \
    --template-body file://./${SYSTEM_NAME}/${STACK_NAME}/${STACK_NAME}.yml \
    --cli-input-json file://./${SYSTEM_NAME}/${STACK_NAME}/${ENV_TYPE}-parameters.json

    aws cloudformation wait stack-create-complete \
    --stack-name ${SYSTEM_NAME}-${ENV_TYPE}-${STACK_NAME}
}

create_stack dev s3
./akane/deploy_app.dev.sh

exit 0
delete_stacks.sh
#!/bin/sh

cd `dirname $0`

SYSTEM_NAME=akane

delete_stack () {
    ENV_TYPE=$1
    STACK_NAME=$2
    aws cloudformation delete-stack \
    --stack-name ${SYSTEM_NAME}-${ENV_TYPE}-${STACK_NAME}

    aws cloudformation wait stack-delete-complete \
    --stack-name ${SYSTEM_NAME}-${ENV_TYPE}-${STACK_NAME}
}

./akane/delete_app.dev.sh
delete_stack dev s3

exit 0

4. デプロイファイル

deploy_app.dev.sh
#!/bin/sh

cd `dirname $0`

BASENAME=$(basename $0)
FILENAME=${BASENAME%.*}
ENV_TYPE=${FILENAME##*.}

APP_DIR=app/build
S3_DIR=s3/

BUCKET_NAME=$(cat ${S3_DIR}${ENV_TYPE}-parameters.json | jq -r '.Parameters[] | select(.ParameterKey == "AppS3Bucket").ParameterValue')

aws s3 cp ${APP_DIR} s3://${BUCKET_NAME} --recursive

exit 0
delete_app.dev.sh
#!/bin/sh

cd `dirname $0`

BASENAME=$(basename $0)
FILENAME=${BASENAME%.*}
ENV_TYPE=${FILENAME##*.}

S3_DIR=s3/

BUCKET_NAME=$(cat ${S3_DIR}${ENV_TYPE}-parameters.json | jq -r '.Parameters[] | select(.ParameterKey == "AppS3Bucket").ParameterValue')

aws s3 rm s3://${BUCKET_NAME} --recursive

exit 0
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0