Udemyレビュー:AWS:ゼロから実践するAmazon Web Services。手を動かしながらインフラの基礎を習得

Udemyレビュー:AWS:ゼロから実践するAmazon Web Services。手を動かしながらインフラの基礎を習得

Udemyレビュー:AWS:ゼロから実践するAmazon Web Services。手を動かしながらインフラの基礎を習得

UdemyにはAWS系のハンズオン講座が多数あります。
本ページでは、以下の講座をご紹介します。

review-handson-001-001

AWS:ゼロから実践するAmazon Web Services。手を動かしながらインフラの基礎を習得

最初に結論

結論を先に書きますと、この講座はAWSで初めてアプリケーションを作成する方にピッタリです。

この講座は「インフラ」の初心者向けに設計されています。
ですからメインテーマであるAWSサービスに関する説明や設定方法はもちろん充実しています。
それに加えて、例えばネットワークやWebサーバ、データベース等の、AWSに限らないITインフラに関する説明も豊富です。
ですからAWSに詳しくない人、またはITインフラに詳しくない人でも、そして今から両方を学びたいと考えている人にオススメです。

この講座を通じて、1つのWebアプリケーション(WordPress)が作成できるようになります。
このアプリの構成は、AWSの実業務でも頻繁に登場するものであり、言わば基本形です。
この講座を受講することによって、AWSの基本構成を身につけることができれば、AWS業務でもすぐに活かせるでしょう。

自己紹介

私は2019年にクラウドプラクティショナーを受験し、合格しました。
またクラウドプラクティショナーの最上位資格であるソリューションアーキテクトプロフェッショナル(SAP)や、DevOpsエンジニアプロフェッショナル(DOP)等も取得しております。

review-clf-001-001

講座の基本情報

今回ご紹介するUdemyは以下の講座です。

review-handson-001-001

AWS:ゼロから実践するAmazon Web Services。手を動かしながらインフラの基礎を習得

動画が中心のハンズオン系です。
14セクションで構成されており、その内実際にハンズオンの内容が含まれているのは11セクションです。

review-handson-001-002

受講者の評価

講座の内容に入る前に、本講座を受講したユーザの評価を見てみましょう。
今回はユーザのコメント(過去1年分(243件))に注目します。

コメントの内容をネガポジ判定します。
一文の各語をネガポジ評価し、ネガティブの場合は-1、ポジティブの場合は1としてカウントします。
この合計値を単語数で割った値で判定します。

ネガポジ判定結果を円グラフにしました。

review-handson-001-003

語のネガポジ評価は東北大学の乾・岡崎研究室の「日本語評価極性辞書」の用言編と名詞編(1)を使用しました。

判定値を以下の通りに分類して、円グラフを作成しています。

  • -1 <= x < -0.5:ネガティブ
  • -0.5 <= x < 0:少しネガティブ
  • 0 <= x < 0.5:少しポジティブ
  • 0.5 <= x < 1:ポジティブ

68.3%のコメントがポジティブ/少しポジティブという結果になりました。
本講座の受講者の大半は内容に満足していることが読み取れます。

続いてコメントからワードクラウドを作成しました。

review-handson-001-004

語の色でネガポジを示しています。
赤がポジティブ、青がネガティブ、灰色はニュートラルな語です。

まずポジティブな語を見ます。
「分かる」や「できる」が非常に大きいです。
この講座を通じて、AWSやITインフラへの理解をが深まり、設計・構築できるスキルが身についたということでしょう。
また「基礎」や「丁寧」も、ニュートラル語である「動画」と合わせて、本講座を特徴付けるキーワードです。
動画を中心としたハンズオンですが、基本的な事項から丁寧な説明があり、操作方法やその意図がバッチリわかります。

次にネガティブな語を見ます。
「大変」や「難しい」が目につきます。
AWSやITインフラに関する知識が浅い方は、まずはそれぞれの知識を身につける必要があるため、そこで苦戦しているように見受けられます。

本講座を受講した方の評価をまとめます。
本講座を受講した方の約7割が、内容に満足しています。
そしてコメントを見ると、この講座を受講することによって、AWSを用いたインフラ構築方法を身につけることができると期待できます。

講座のポイント

以下に本講座を受講するメリットを3点ご紹介します。

  1. 構築するアプリケーション
  2. 丁寧な解説
  3. 十分なハンズオン

① 構築するアプリケーション

本講座を通じて作成するアプリケーションは、3層アーキテクチャと呼ばれるものです。
これはAWSの実業務で出会うことが多い構成です。

AWS公式でも、この3層アーキテクチャを以下の通りに説明しています。

3 層アーキテクチャは、多層アーキテクチャの最も一般的な実装であり、1 つのプレゼンテーション層、ロジック層、データ層で構成されます。

3 層アーキテクチャの概要

つまりITインフラ初心者の方が触れる最初の構成という意味では、この講座で作成するアプリケーションは、最も適切なものだと言えるでしょう。

以下が本講座で作成するアプリケーションの構成図です。

review-handson-001-000

VPC内のサービスを見ますと、ALBを配置し、その配下に2つのEC2インスタンスを配置します。
EC2インスタンス上では、ApacheやPHP等をインストールして、WordPressを動作させます。
そしてDBサーバとしてMySQLタイプのRDSインスタンスを作成し、Web・アプリ層とDB層を分離させます。
RDSインスタンスはマルチAZ配置として、冗長化します。

VPC外のサービスを見ますと、Route 53に独自ドメインを登録して、同ドメインから自作アプリにアクセスできるようになります。

S3バケットを作成して、同バケット上に画像等の静的コンテンツを配置します。
これはWordPressのプラグイン(WP Offload Media Lite for Amazon S3)で実現します。

CDNとして、CloudFrontを使用します。
画像等を同ディストリビューションから配信します。

CloudWatchでEC2インスタンスのCPU使用率を計測します。
使用率が高まった場合は、SNS経由を通じて、メールにて通知します。

この構成は、AWSの実業務において頻繁に出会います。
つまりこの講座を学習することで、AWS案件で即戦力として働けるようになるでしょう。

② 丁寧な解説

前提となるITインフラの知識から解説

上記で述べたように、本講座はAWSに限らず、ITインフラの初心者に向けて設計されています。
ですから初心者にも伝わるように、技術的な要素が丁寧に解説されています。

ITインフラに関する説明の一例として、以下にネットワーク、特にIPアドレスに関する解説を引用します。

review-handson-001-005

ITインフラにおいて、ネットワークに関する知識は不可欠です。
そしてIPアドレスはネットワークにおける最も初歩の知識です。

上記の画像のように、丁寧なスライドを用いた解説があります。
このようにITインフラ未経験な方でも、安心して学習を継続することができます。

AWS知識も丁寧に解説

各セクションの構成は以下の流れです。

  1. セクションのねらい・構築するものの説明
  2. セクションに関係するITインフラに関する説明
  3. AWSでの構築方法の説明(ハンズオン)
  4. セクションで学んだことの振り返り

ITインフラに関する説明とは、例えばネットワークですと、先述のIPアドレスやサブネット、ルーティングがこれに該当します。
AWSでの構築方法の説明とは、例えばネットワークですと、VPCにおけるパブリック/プライベートサブネット、ルートテーブルです。

AWSでの構築方法の説明の一例として、以下にVPCにおけるハンズオンに関する解説を引用します。

review-handson-001-006

作成するリソースを図示することで、受講者がより具体的にイメージを掴むことができます。
また作業内容が簡潔に整理されており、受講者の理解をサポートしています。
このようにAWS未経験の方でも、無理なくハンズオンを進めることができます。

スライド数の調査

参考として、ITインフラに関する説明動画に注目し、その動画内で使用されているスライド数のヒストグラムを作成しました。

review-handson-001-007

基本統計量も載せます。

統計量ITインフラ説明動画ハンズオン動画
度数50.00000038.000000
平均4.6200002.447368
標準偏差2.9477771.082973
最小値1.0000001.000000
第一四分位数3.0000002.000000
中央値4.0000002.000000
第三四分位数6.0000003.000000
最大値17.0000007.000000

それぞれのカテゴリで平均値と中央値の値が概ね合致しています。
つまりITインフラ説明動画では、平均して4枚程度のスライドを使って、インフラに関する基本的な知識に関して説明されます。
そしてハンズオン動画では、平均して2枚程度のスライドを使って、ハンズオンの作業内容やその意味について説明されます。

以上をまとめますと、本講座は丁寧な作りのスライドを豊富に使って、ITインフラおよびAWSハンズオンに関して説明があります。
初学者が挫折することなく、学習を継続することができるでしょう。

③ 十分なハンズオン

本講座のメインコンテンツであるハンズオン動画に関して取り上げます。

ワンカットで丁寧な動画

本講座のハンズオン動画は、実際に作者がAWSマネジメントコンソールを操作している動画となります。
本講座のハンズオン動画の特徴は、ワンカット、つまり編集なしで操作が録画されているという点です。
ハンズオン系のUdemy講座でありがちなのですが、尺を短くするために、ポイントとなる操作だけが動画で説明される場合があります。
これではポイントの前後の操作が不明ですし、それが原因でポイントとなる操作まで辿り着けないこともしばしばあります。
この講座のハンズオン動画は、そういった心配は不要です。
受講者は目的の操作をするために、コンソールのどこをどのように操作すれば良いのかを、操作の最初から最後まで確認することができます。
この講座のハンズオン動画であれば、AWS初心者の方でもコンソール画面で迷わず、安心して操作することができます。

コンソール画面のアップデート対応

この講座のもう1つの特徴に、マネジメントコンソールのアップデートへの対応が挙げられます。
ご存知の方もおられると思いますが、AWSマネジメントコンソールのGUIは頻繁に更新されます。
ですからハンズオン動画で写されている画面が、古いバージョンのものになってしまうことも頻繁にあります。
これに対応するために、本講座では、アップデートされた内容をPDFで補完する対応をとっています。

1つ例を挙げます。
コース内容の一覧の中で、EC2インスタンスWebサーバを構築するセクションを見ます。

review-handson-001-008

このセクションの3つ目のコンテンツに、「リソース」というものがあります。
これがアップデート対応用のPDFです。

以下にこのPDFの一部を引用します。

review-handson-001-009

最新のGUIでの作業手順です。
このように本講座は、マネジメントコンソールの更新にもしっかりと対応しています。
多少、動画自体が古くなったとしても、PDF等で最新版の手順を確認することができます。

ハンズオン時間の調査

参考として、ハンズオン動画において、実際にコンソール画面を操作している秒数に関するヒストグラムを作成しました。

review-handson-001-010

基本統計量も載せます。

統計量ハンズオン動画
度数38.000000
平均457.210526
標準偏差318.907015
最小値66.000000
第一四分位数206.750000
中央値378.000000
第三四分位数579.250000
最大値1481.000000

中央値が約380秒、平均値が約450秒ですから、大半の動画が6~7分だということがわかります。

グラフを見ると、600秒内の動画が多いですね。
600秒を超える動画は8つで、全体の75%が600秒以内です。

つまり多くの動画において、ハンズオンタイムは10分以内ということです。
一説では、人間が深く集中できる時間は15分が限界と言われています。
そういった意味では、長すぎず、短すぎず、適切な分量だと言えるのではないでしょうか。

まとめ

AWSハンズオン系の講座として、以下のコンテンツをご紹介しました。

review-handson-001-001

AWS:ゼロから実践するAmazon Web Services。手を動かしながらインフラの基礎を習得

この講座を通じて構築するアプリケーションは、初めてITインフラを触る方が最初に知るべき様々な内容が盛り込まれており、ITインフラを全般を満遍なく学ぶことができます。そしてアプリケーションは、実際のAWS業務においても頻出の構成でもあるため、実業務で即戦力として活躍できるようになるでしょう。
この講座では、ITインフラや構築するアプリケーションに関して、丁寧なスライドを使った説明があります。ITインフラやAWSに関して初学者であっても、学習に躓くことがないように配慮されています。
この講座のメインコンテンツであるハンズオンに関しては、十分な時間が確保されています。またマネジメントコンソールのGUI画面が更新された場合も、別途PDFファイルを配布することで、最新版の手順を提示してくれます。
AWSを使ってアプリケーションを作って見たい方は、ぜひ購入を検討されてはいかがでしょうか。

(おまけ) CloudFormationを使用して、本講座の構成を再現

本講座はマネジメントコンソール、つまりGUIを使ってアプリケーションを構築する手順が紹介されています。
本章では、オマケとして、CloudFormationを使って、自動的に本講座に近い環境を構築する方法をご紹介します。

構築する環境

review-handson-001-999

構成は講座のものとほとんど同じです。

唯一独自な構成があります。
それはImage Builderを使用する点です。
EC2インスタンスを作成する際に、WordPressが構築済みのAMIを準備する必要があるためです。

なお今回Route53に登録するカスタムドメインは、Route53で取得したもの(awstut.net)を使用します。

CloudFormationテンプレートファイル

上記の構成をCloudFormationで構築します。
以下のURLにCloudFormationテンプレートを配置しています。

https://github.com/awstut-an-r/awstut-udemy/tree/main/001

テンプレートファイルのポイント解説

本構成のポイントを取り上げます。
本章はオマケということで、既に本講座を受講済みの方に向けた簡易的な解説となります。

VPC

Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: !Ref VPCCidrBlock

  IGW:
    Type: AWS::EC2::InternetGateway

  IGWAttachment:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref VPC
      InternetGatewayId: !Ref IGW

  PublicSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: !Sub "${AWS::Region}${AvailabilityZone1}"
      CidrBlock: !Ref CidrIp1
      VpcId: !Ref VPC

  PublicSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: !Sub "${AWS::Region}${AvailabilityZone2}"
      CidrBlock: !Ref CidrIp2
      MapPublicIpOnLaunch: true
      VpcId: !Ref VPC

  PrivateSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: !Sub "${AWS::Region}${AvailabilityZone1}"
      CidrBlock: !Ref CidrIp3
      VpcId: !Ref VPC

  PrivateSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: !Sub "${AWS::Region}${AvailabilityZone2}"
      CidrBlock: !Ref CidrIp4
      VpcId: !Ref VPC

  PublicRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC

  RouteToInternet:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref PublicRouteTable
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref IGW

  PublicSubnetRouteTableAssociation1:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet1
      RouteTableId: !Ref PublicRouteTable

  PublicSubnetRouteTableAssociation2:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet2
      RouteTableId: !Ref PublicRouteTable

  ALBSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupName: !Sub "${Prefix}-ALBSecurityGroup"
      GroupDescription: Allow HTTP Only.
      VpcId: !Ref VPC
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: !Ref HTTPPort
          ToPort: !Ref HTTPPort
          CidrIp: 0.0.0.0/0

  InstanceSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupName: !Sub "${Prefix}-InstanceSecurityGroup"
      GroupDescription: Allow HTTP from ALBSecurityGroup.
      VpcId: !Ref VPC
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: !Ref HTTPPort
          ToPort: !Ref HTTPPort
          SourceSecurityGroupId: !Ref ALBSecurityGroup

  DBSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupName: !Sub "${Prefix}-DBSecurityGroup"
      GroupDescription: Allow MySQL from Instance.
      VpcId: !Ref VPC
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: !Ref MySQLPort
          ToPort: !Ref MySQLPort
          SourceSecurityGroupId: !Ref InstanceSecurityGroup
Code language: YAML (yaml)

VPC内に4つのサブネットを作成します。

2つはインターネットゲートウェイと関連付けるパブリックサブネット、残りの2つはプライベートサブネットです。
2種類のサブネットはAZを分けます。

パブリックサブネットにはインターネットゲートウェイ向けのデフォルトルートを持つルートテーブルをアタッチします。

3つのセキュリティグループを作成します。
ALB・EC2インスタンス・RDS DBインスタンス用です。

RDS

Resources:
  DBInstance:
    Type: AWS::RDS::DBInstance
    DeletionPolicy: Delete
    Properties:
      AllocatedStorage: !Ref DBAllocatedStorage
      DBInstanceClass: !Ref DBInstanceClass
      DBInstanceIdentifier: dbinstance
      DBName: !Ref DBName
      DBSubnetGroupName: !Ref DBSubnetGroup
      Engine: !Ref DBEngine
      EngineVersion: !Ref DBEngineVersion
      MasterUsername: !Ref DBMasterUsername
      MasterUserPassword: !Ref DBMasterUserPassword
      MultiAZ: true
      VPCSecurityGroups:
        - !Ref DBSecurityGroup

  DBSubnetGroup:
    Type: AWS::RDS::DBSubnetGroup
    Properties:
      DBSubnetGroupName: dbsubnetgroup
      DBSubnetGroupDescription: dbsubnetgroup.
      SubnetIds:
        - !Ref PrivateSubnet1
        - !Ref PrivateSubnet2
Code language: YAML (yaml)

プライベートサブネットにDBインスタンスを作成します。

マルチAZ機能を有効化します。
本機能に関する基本的な事項に関しましては、以下のページもご確認ください。

あわせて読みたい
CFNでマルチAZ配置のRDSを作成する 【CloudFormationを使用して、マルチAZ配置のRDSを作成する】 RDSが提供する機能の1つにマルチAZ配置があります。 Amazon RDS マルチ AZ 配置では、Amazon RDS はプライ...

Image Builder

Resources:
  Component:
    Type: AWS::ImageBuilder::Component
    Properties:
      Data: !Sub |
        schemaVersion: 1.0
        phases:
          - name: build
            steps:
              - name: InstallWordPress
                action: ExecuteBash
                inputs:
                  commands:
                    - yum update -y
                    - yum install -y httpd
                    - amazon-linux-extras enable -y php7.4

                    - yum install -y php php-gd php-mysqlnd php-xmlrpc

                    - systemctl start httpd
                    - systemctl enable httpd

                    - cd /var/www/html

                    - curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
                    - chmod +x wp-cli.phar
                    - mv wp-cli.phar /usr/local/bin/wp
                    - wp core download --locale=ja
                    - wp core config --dbname="${DBName}" --dbuser="${DBMasterUsername}" --dbpass="${DBMasterUserPassword}" --dbhost="${DBInstanceEndpointAddress}"
                    - wp core install --url="http://${DomainName}" --title="${WordPressTitle}" --admin_user="${WordPressAdminUser}" --admin_password="${WordPressAdminPassword}" --admin_email="${WordPressAdminEmail}"

                    - wp plugin install amazon-s3-and-cloudfront --activate
                    - wp option update tantan_wordpress_s3 '{"bucket":"${BucketName}","region":"${AWS::Region}","use-server-roles":true,"copy-to-s3":true,"delivery-provider":"aws","enable-delivery-domain":true,"delivery-domain":"static.${DomainName}"}' --format=json

                    - chmod 757 -R ./wp-content/uploads
      Name: !Sub "${Prefix}-Component"
      Platform: !Ref ImageBuilderPlatform
      SupportedOsVersions:
        - !Ref ImageBuilderSupportedOsVersion
      Version: !Ref ImageBuilderVersion

  ImageRecipe:
    Type: AWS::ImageBuilder::ImageRecipe
    Properties:
      Components:
        - ComponentArn: !Ref Component
      Name: !Sub "${Prefix}-ImageRecipe"
      ParentImage: !Ref ImageBuilderParentImage
      Version: !Ref ImageBuilderVersion

  InfrastructureConfiguration:
    Type: AWS::ImageBuilder::InfrastructureConfiguration
    Properties:
      InstanceProfileName: !Ref ImageBuilderRoleProfile
      InstanceTypes:
        - !Ref InstanceType
      Name: !Sub "${Prefix}-InfrastructureConfiguration"
      SecurityGroupIds:
        - !Ref InstanceSecurityGroup
      SnsTopicArn: !Ref Topic1
      SubnetId: !Ref PublicSubnet2

  DistributionConfiguration:
    Type: AWS::ImageBuilder::DistributionConfiguration
    Properties:
      Distributions:
        - Region: !Ref AWS::Region
          AmiDistributionConfiguration: {}
      Name: !Sub "${Prefix}-DistributionConfiguration"

  ImagePipeline:
    Type: AWS::ImageBuilder::ImagePipeline
    Properties:
      DistributionConfigurationArn: !Ref DistributionConfiguration
      ImageRecipeArn: !Ref ImageRecipe
      InfrastructureConfigurationArn: !Ref InfrastructureConfiguration
      Name: !Sub "${Prefix}-ImagePipeline"
      Status: ENABLED

  ImageBuilderRoleProfile:
    Type: AWS::IAM::InstanceProfile
    Properties:
      Path: /
      Roles:
        - !Ref ImageBuilderRole

  ImageBuilderRole:
    Type: AWS::IAM::Role
    DeletionPolicy: Delete
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Action: sts:AssumeRole
            Principal:
              Service:
                - ec2.amazonaws.com
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
        - arn:aws:iam::aws:policy/EC2InstanceProfileForImageBuilder
Code language: YAML (yaml)

Image Builderパイプラインを動作させるために、いくつかのリソースを作成します。
Image Builderに関する詳細な説明につきましては、以下のページをご確認ください。

あわせて読みたい
CloudFormationを使用して、EC2 Image Builder入門 【CloudFormationを使用して、EC2 Image Builder入門】 本ページではEC2 Image Builderを取り上げます。 Image Builder は、シンプルなグラフィカルインターフェイス、...

またImage Builderを使用して、WordPress用のAMIを作成する方法については、以下のページをご確認ください。

あわせて読みたい
Image Builderを使用して、WordPress用のAMIを作成する 【Image Builderを使用して、WordPress用のAMIを作成する】 以下のページで、Image Builderについて取り上げました。 https://awstut.com/2023/10/28/introduction-to-e...

特にポイントとなるリソースはComponentです。
本リソースで、AMIを構築するために実行する処理を定義します。
今回はWordPress環境を構築するために、ApacheやPHP、そしてWordPress本体のインストールやセットアップに関するコマンドを定義します。
WordPressのインストール・セットアップは、WP-CLIを使用します。

https://wp-cli.org/ja/

WP-CLIを使用することで、DBのユーザ名やパスワード、エンドポイント等の基本的な設定に加えて、プラグイン(WP Offload Media)のインストールやセットアップも行います。
なおWP-CLIを用いて同プラグインをセットアップする方法については、以下のページを参考にしました。

https://blog.imo-tikuwa.com/aws-cloudformation-multiaz-wordpress4/

EC2

Resources:
  Instance1:
    Type: AWS::EC2::Instance
    Properties:
      IamInstanceProfile: !Ref InstanceProfile
      ImageId: !Sub "{{resolve:ssm:${ParameterAmi}}}"
      InstanceType: !Ref InstanceType
      NetworkInterfaces:
        - AssociatePublicIpAddress: true
          DeviceIndex: 0
          GroupSet:
            - !Ref InstanceSecurityGroup
          SubnetId: !Ref PublicSubnet1

  Instance2:
    Type: AWS::EC2::Instance
    Properties:
      IamInstanceProfile: !Ref InstanceProfile
      ImageId: !Sub "{{resolve:ssm:${ParameterAmi}}}"
      InstanceType: !Ref InstanceType
      NetworkInterfaces:
        - AssociatePublicIpAddress: true
          DeviceIndex: 0
          GroupSet:
            - !Ref InstanceSecurityGroup
          SubnetId: !Ref PublicSubnet2

  InstanceProfile:
    Type: AWS::IAM::InstanceProfile
    Properties:
      Path: /
      Roles:
        - !Ref InstanceRole

  InstanceRole:
    Type: AWS::IAM::Role
    DeletionPolicy: Delete
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Action: sts:AssumeRole
            Principal:
              Service:
                - ec2.amazonaws.com
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
        - arn:aws:iam::aws:policy/AmazonS3FullAccess
Code language: YAML (yaml)

2台のEC2インスタンスを作成します。
両インスタンスはパブリックアドレスに配置し、パブリックアドレスを付与します。

インスタンス用のIAMロールを見ると、2つのAWS管理ポリシーがアタッチされています。
1つ目(AmazonSSMManagedInstanceCore)は、インスタンスにSSM Session Managerを使用してアクセスするためのものです。
2つ目(AmazonS3FullAccess)はWP Offload Mediaを正常に動作させるためのものです。

ALB

Resources:
  ALB:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      Name: !Sub "${Prefix}-ALB"
      Scheme: internet-facing
      SecurityGroups:
        - !Ref ALBSecurityGroup
      Subnets:
        - !Ref PublicSubnet1
        - !Ref PublicSubnet2
      Type: application

  ALBTargetGroup:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      VpcId: !Ref VPC
      Name: !Sub "${Prefix}-ALBTargetGroup"
      Protocol: HTTP
      Port: !Ref HTTPPort
      HealthCheckProtocol: HTTP
      HealthCheckPath: /
      HealthCheckPort: traffic-port
      HealthyThresholdCount: !Ref HealthyThresholdCount
      UnhealthyThresholdCount: !Ref UnhealthyThresholdCount
      HealthCheckTimeoutSeconds: !Ref HealthCheckTimeoutSeconds
      HealthCheckIntervalSeconds: !Ref HealthCheckIntervalSeconds
      Matcher:
        HttpCode: !Ref HttpCode
      TargetGroupAttributes:
        - Key: stickiness.enabled
          Value: true
        - Key: stickiness.lb_cookie.duration_seconds
          Value: 86500
      Targets:
        - Id: !Ref Instance1
        - Id: !Ref Instance2

  ALBListener:
    Type: AWS::ElasticLoadBalancingV2::Listener
    Properties:
      DefaultActions:
        - TargetGroupArn: !Ref ALBTargetGroup
          Type: forward
      LoadBalancerArn: !Ref ALB
      Port: !Ref HTTPPort
      Protocol: HTTP
Code language: YAML (yaml)

ALBはパブリックサブネットに関連付けます。
ターゲットグループとして、2台のEC2インスタンスを指定します。
HTTPトラフィックをこのターゲットグループにルーティングします。

ALBはパブリックサブネットに関連付けます。
ターゲットグループとして、2台のEC2インスタンスを指定します。
HTTPトラフィックをこのターゲットグループにルーティングします。

ALBに関する基本的な事項は、以下のページもご確認ください。

あわせて読みたい
プライベートサブネット内のインスタンスをALBにアタッチする 【プライベートサブネット内のインスタンスをALBにアタッチする構成】 プライベートサブネット内に設置されたインスタンスを、ALBにアタッチする方法を確認します。 AWS...

SNS

Resources:
  Topic2:
    Type: AWS::SNS::Topic
    Properties:
      Subscription:
        - Endpoint: !Ref MailAddress
          Protocol: email
      TopicName: !Sub "${Prefix}-topic-02"
Code language: YAML (yaml)

SNSトピックにサブスクライブします。
今回はエンドポイントとして、メールアドレスを指定します。

SNSを使用したメール通知については、以下のページもご確認ください。

あわせて読みたい
CFNでSNS入門 – email版 【CFNでSNS入門 - email版】 AWS SNSはメッセージングサービスです。 今回は入門編ということで、通知先にEmailを指定する方法をご紹介します。 【構築する環境】 2種類...

CloudWatch

Resources:
  Alarm1:
    Type: AWS::CloudWatch::Alarm
    Properties:
      AlarmActions:
        - !Ref Topic2
      AlarmName: !Sub "${Prefix}-alarm-01"
      ComparisonOperator: !Ref ComparisonOperator
      Dimensions:
        - Name: !Ref DimensionName
          Value: !Ref Instance1
      EvaluationPeriods: !Ref EvaluationPeriods
      MetricName: !Ref MetricName
      Namespace: !Ref Namespace
      Period: !Ref Period
      Statistic: !Ref Statistic
      Threshold: !Ref Threshold

  Alarm2:
    Type: AWS::CloudWatch::Alarm
    Properties:
      AlarmActions:
        - !Ref Topic2
      AlarmName: !Sub "${Prefix}-alarm-02"
      ComparisonOperator: !Ref ComparisonOperator
      Dimensions:
        - Name: !Ref DimensionName
          Value: !Ref Instance2
      EvaluationPeriods: !Ref EvaluationPeriods
      MetricName: !Ref MetricName
      Namespace: !Ref Namespace
      Period: !Ref Period
      Statistic: !Ref Statistic
      Threshold: !Ref Threshold
Code language: YAML (yaml)

CPU使用率に応じて、アラームさせます。
今回は使用率の平均が10%を超えた場合に、先ほどのSNSを通じてメール通知させます。
今回は2台のインスタンスがありますので、2つのアラームを作成します。

CPUが閾値を超えた時にメール通知する方法については、以下のページもご確認ください。

あわせて読みたい
ECSのCPU使用率が閾値を超えた時にCloudWatchアラームでメール通知する 【ECS(Fargate)のCPU使用率が閾値を超えた時に、CloudWatchアラームからSNSでメール通知する】 FargateタイプのECSを作成すると、デフォルトでCPUとメモリ使用率がCloud...

S3

Resources:
  Bucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Ref Prefix
      PublicAccessBlockConfiguration:
        BlockPublicAcls: false
        BlockPublicPolicy: false
        IgnorePublicAcls: false
        RestrictPublicBuckets: false

  BucketPolicy:
    Type: AWS::S3::BucketPolicy
    Properties:
      Bucket: !Ref Bucket
      PolicyDocument:
        Statement:
          Action:
            - s3:GetObject
          Effect: Allow
          Principal: "*"
          Resource: !Sub "arn:aws:s3:::${Bucket}/*"
Code language: YAML (yaml)

S3バケットを作成します。

WP Offload Mediaを正常に動作させるために、2つの設定を行います。

1つ目はバケットのPublicAccessBlockConfigurationプロパティです。
この内部の設定を全てfalseとすることで、ブロックを無効化します。

2つ目はバケットポリシーを設定します。
バケット内のオブジェクトへのアクセスを許可する内容です。

ACM

Resources:
  Certificate:
    Type: AWS::CertificateManager::Certificate
    Properties:
      DomainName: !Sub "*.${DomainName}"
      DomainValidationOptions:
        - DomainName: !Ref DomainName
          HostedZoneId: !Ref HostedZoneId
      ValidationMethod: DNS
Code language: YAML (yaml)

後述するCloudFront用にACM証明書を取得します。

こちらはus-east-1リージョンに作成することにご注意ください。

CloudFront

Resources:
  Distribution:
    Type: AWS::CloudFront::Distribution
    Properties:
      DistributionConfig:
        Aliases:
          - !Sub "static.${DomainName}"
        DefaultCacheBehavior:
          AllowedMethods:
            - GET
            - HEAD
          CachedMethods:
            - GET
            - HEAD
          Compress: true
          ForwardedValues:
            Cookies:
              Forward: none
            QueryString: false
          TargetOriginId: !Ref BucketName
          ViewerProtocolPolicy: redirect-to-https
          DefaultTTL: !Ref CacheTTL
          MaxTTL: !Ref CacheTTL
          MinTTL: !Ref CacheTTL
        Enabled: true
        Origins:
          - DomainName: !Ref BucketRegionalDomainName
            Id: !Ref BucketName
            S3OriginConfig:
              OriginAccessIdentity: ""
        PriceClass: PriceClass_All
        ViewerCertificate:
          AcmCertificateArn: !Ref Certificate
          SslSupportMethod: sni-only
Code language: YAML (yaml)

CloudFrontディストリビューションのオリジンとして、S3バケットを指定します。

先ほどのACM証明書を指定します。

Route53

Resources:
  DnsRecord1:
    Type: AWS::Route53::RecordSet
    Properties:
      AliasTarget:
        DNSName: !Ref ALBDNSName
        HostedZoneId: !Ref ALBHostedZoneId
      HostedZoneId: !Ref DomainHostedZoneId
      Name: !Ref DomainName
      Type: A

  DnsRecord2:
    Type: AWS::Route53::RecordSet
    Properties:
      HostedZoneId: !Ref DomainHostedZoneId
      Name: !Sub "static.${DomainName}"
      ResourceRecords:
        - !Ref DistributionDomainName
      TTL: !Ref TTL
      Type: CNAME
Code language: YAML (yaml)

2つのレコードを作成します。
1つ目はALBへのアクセスを、カスタムドメイン(awstut.net)を通じて実施できるようにするためのものです。
2つ目はCloudFrontから画像を配信する際に、カスタムドメインのCNAME(static.awstut.net)を指定して実施できるようにするためのものです。

環境構築

CloudFormationを使用して、本環境を構築し、実際の挙動を確認します。

CloudFormationスタックを作成し、スタック内のリソースを確認する

CloudFormationスタックを作成します。
スタックの作成および各スタックの確認方法については、以下のページをご確認ください。

あわせて読みたい
CloudFormationのネストされたスタックで環境を構築する 【CloudFormationのネストされたスタックで環境を構築する方法】 CloudFormationにおけるネストされたスタックを検証します。 CloudFormationでは、スタックをネストす...

今回ですと、具体的には以下の手順となります。

まず任意のS3バケットにテンプレートファイルをアップロードします。

$ aws s3 cp . s3://[bucket-name]/[folder-name]/ \
--recursive
Code language: Bash (bash)

次にCloudFormationスタックを作成します。

今回は2回に分けます。

まず1回目のスタックを作成します。

$ aws cloudformation create-stack \
--stack-name udemy-001 \
--template-url https://[bucket-name].s3.ap-northeast-1.amazonaws.com/[folder-name]/udemy-001-acm.yaml \
--region us-east-1
Code language: Bash (bash)

こちらのスタック作成が完了したら2回目のスタックを作成します。

$ aws cloudformation create-stack \
--stack-name udemy-001 \
--template-url https://[bucket-name].s3.ap-northeast-1.amazonaws.com/[folder-name]/udemy-001.yaml \
--parameters ParameterKey=ACMCertificate,ParameterValue=arn:aws:acm:us-east-1:[account-id]:certificate/[certificate-id] \
--capabilities CAPABILITY_IAM \
--region ap-northeast-1
Code language: Bash (bash)

スタックの作成が完了すると、登録したアドレスにメールが届きます。
SNSのメール認証です。

詳細については以下のページをご確認ください。

あわせて読みたい
CFNでSNS入門 – email版 【CFNでSNS入門 - email版】 AWS SNSはメッセージングサービスです。 今回は入門編ということで、通知先にEmailを指定する方法をご紹介します。 【構築する環境】 2種類...

動作確認

準備が整いましたので、WordPressサイトにアクセスします。

review-handson-001-011

独自ドメインからWordPressサイトにアクセスすることができました。
このことからALB/EC2/RDSでアプリケーションが構築されていることや、Image BuilderでWordPressのインストール済みのAMIがビルドされて、これを使ってEC2インスタンスが作成されていることもわかります。

管理ページにアクセスします。

review-handson-001-012

プラグインを見ると、WP Offload Mediaがインストールされています。

review-handson-001-013

設定を見ると、CNAMEにCloudFrontのCNAMEである「static.awstut.net」が指定されています。

記事にサンプルの画像を配置します。

review-handson-001-014
review-handson-001-015

配置した画像の情報を見ると、確かにCloudFront経由で配信されていることがわかります。

review-handson-001-016

CloudFrontのオリジンであるS3バケットを見ると、確かに画像がアップロードされています。

SSM Session Managerを使用して、インスタンスの1台にアクセスします。

% aws ssm start-session --target [instance-id]
...

sh-4.2$Code language: Bash (bash)

Session Managerに関しては、以下のページをご確認ください。

あわせて読みたい
LinuxインスタンスにSSM Session Manager経由でアクセスする 【LinuxインスタンスにSSM Session Manager経由でアクセスする】 EC2インスタンスにSSM Session Manager経由でアクセスする構成を確認します。 Session Manager は完全...

yesコマンドを使用して、CPU使用率を高めます。

sh-4.2$ yes > /dev/nullCode language: Bash (bash)

しばらく待つと、CloudWatch Alarmが動作します。

review-handson-001-017

すぐにメールが届きました。

review-handson-001-018

確かにインスタンスの状況をモニタリングし、通知することができました。