実施内容
以下のハンズオンを一通り行う
https://aws.amazon.com/jp/aws-jp-introduction/aws-jp-webinar-hands-on/
ハンズオンの内容が古いものもあったので、2020/11〜12月時点の方法で実行する。
(削除のセッションは基本的に割愛)
なお、筆者のAWSアカウントでは、Cloud9のデプロイが何度も失敗していたので、基本的にEC2インスタンスをCloud9の代わりに構築して作業を行なっている。
EC2上では、後述のCloudFormationコマンドを実行するために以下の設定を行った。
- PowerUserAccessのIAMを付与したユーザを作成
- そのユーザのアクセスキー等をコピー
- EC2にSSHアクセスし、aws configureと入力
- ユーザのアクセスキーを入力
- ユーザのシークレットキーを入力
- リージョンを選択、東京の場合はap-northeast-1
- コマンド出力結果の表示形式を指定(jsonやtableを入力)
PowerUserAccessはテンプレの中で2番目に強い権限を持ったポリシーで、IAM以外の操作が全て行えるユーザ。
なお、この設定ではハンズオン9でエラーが出たため、その時に解決を行う。
##1:ハンズオンはじめの一歩
アカウントの作成
個人情報等を入力してアカウントを作成する
クレジットカードが必要であるため注意
サポートプランの選択も可能(後で変更も可能)
IAMの作成
アカウント作成時点でできたユーザはルートユーザで全ての権限を持つ
以下のことはルートユーザでしかできない模様
- EC2メール送信制限解除申請(IPアドレス逆引き申請)
- 侵入テスト申請
- CloudFrontのキーペア作成
- AWSサポートプランの変更
- 請求情報に対する IAM ユーザーアクセスの許可
ここでは以下の3ユーザを作成
- 管理ユーザ: 権限...AdministratorAccess
- S3読み込みユーザ: 権限...AmazonS3ReadOnlyAccess
- 権限無しユーザ: 権限...無し
権限は既存のポリシーを直接アタッチで付与できる。
なお、この権限を付与したグループをあらかじめ作っておき、ユーザへアタッチすることも可能
ログインには
- アカウント自体のアカウントID(12桁)
- 作成したユーザ名
- 作成したパスワード
でログインする
IAMには3種類がある
- IAMポリシー:アクセス許可の定義を行うJSONドキュメント。独自ポリシーを作成できる
- IAMグループ:IAMユーザの集合を定義。複数ユーザに容易にアクセス権限を付与できる
- IAMロール:リソースへの権限の付与(S3へのアクセスロールを作成し、EC2に付与することでEC2からS3の操作が可能になる)
IAMポリシーはAWS Policy Generatorで簡単に作ることが可能
https://awspolicygen.s3.amazonaws.com/policygen.html
以下のようなものを作成
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1605838389450",
"Action": [
"ec2:Describe*",
"ec2:StartInstances",
"ec2:StopInstances"
],
"Effect": "Allow",
"Resource": "*"
}
]
}
Describe*のようにワイルドカードの指定も可能
名前を付与し、作成することで、ポリシーの一覧に表示されるようになる
これはユーザに直接付与することもグループに付与することも可能
IAMロールはEC2などのインスタンスに付与することが可能
ロールの作成から各サービスごとのIAMを作成
EC2のインスタンス一覧画面で付与したいEC2にチェックを入れ、アクション>セキュリティ>IAMロールを変更を選択
これで付与されたEC2インスタンスはIAMで与えられた権限を持つことになる
##2:Security #1
※ログ関連の作業は初回ログの取得までに数分から1日まで時間がかかることがあるため注意
コンプライアンス関連
コンプライアンス関連の資料は以下を参照することができる
https://aws.amazon.com/jp/compliance/
ルートユーザの設定およびパスワードポリシー
ルートユーザは完全なアクセス権限を持っているため日常的に使わない
利用者ごとにIAMユーザを作成することが基本
ルートユーザに以下を設定
- ***多要素認証(MFA)***の有効化
- ルートユーザーアクセスキーの削除
- IAMパスワードポリシーの適用
IAMを開き、セキュリティステータスが完了していないものは!マークが付いているため対応が必要
MFAの有効化をクリックし、仮装MFAデバイスを選択。
対応するアプリをスマートフォンにインストール(ここではGoogle Authenticatorを選択)し、画面のバーコードを読み取り。認証コード1、2を入力。
ここが少しわかりづらいが、認証コードは時間が経つと更新されるので、認証コード1は現在画面に表示されているコードを入力し、認証コード2はその次に入力されたコードを入力する
アクセスキーは作ったことがあれば削除する
パスワードポリシーはアカウント設定>パスワードポリシーを変更するから変更可能
IAMユーザのパスワードの入力ルール(最小文字数など)を設定できる
IAMユーザ
ルートユーザ以外でログインするためにIAMユーザを作成する
以下の理解が必要
- IAMユーザ:AWS操作用ユーザ
- IAMグループ:IAMユーザをまとめるグループ
- IAMポリシー:AWSサービス操作に対する権限設定、IAMユーザやIAMグループに対して設定
- IAMロール:AWSサービスやアプリケーション等に対してAWSリソースの操作権限を付与するための仕組み
※ここは1:ハンズオンはじめの一歩とほとんど同じなので割愛
請求データ確認とアラート
以下を実施
- AWS Budgetを使った請求アラート
- AWS CostExplorerの有効化と確認
- AWS Cost & Usage Reportの設定
サービスを検索にBillingと入力し、Billing Management Consoleに移動
コストエクスプローラを有効化をクリック
メニューからBudgetをクリックし、予算を作成するを選択
ここでは期間を月ごとを選択し、予算は15ドル、閾値を60%(9ドルでアラート)にする。
これで閾値を超えた際にメールが送信される
定期的にメールが欲しい場合はBudget Reportを選択し、予算レポートを作成するをクリックし、先ほど作った予算名にチェックを入れ、日次、週次、月次の定期レポートを受け取ることができる。
各リソースがどれだけの金額を発生しているか確認するためにCost & Usage Reportを選択し、レポートの作成をクリックし、格納したいS3バケットを設定する。
プレフィックスが現在は必須となっているため好きな文字列を入力しておく
詳細のコストはCost Explorerを開き、Cost Explorerタブをクリック(初期状態はホーム)することで確認することができる
操作履歴とリソース変更履歴の記録
操作履歴:AWS CloudTrailを利用してAWSサービスを利用する際に行動履歴をログに記録し監視
リソース変更履歴:AWS Configにてリソースの変更履歴・構成情報を管理・監視
検索エリアでCloudTrailと入力し、サービスに移動。
イベント履歴タブから全ての履歴を確認できる。
イベント名を選択し、ConsoleLoginなどを入力することで表示を一部に限定することも可能。
行動履歴を記録するために、証跡の作成をクリックする。
指定したS3にJson形式のログが格納されるようになる。
次に、検索エリアにConfigと入力し、サービスに移動。
今すぐ始めるボタンをクリックする。
設定は標準のままで可能。
AWS Configルールはある一定のルールに則っていないと通知を出すもの。今回は使わないのでスキップ。
作成後、各サービスの一覧が表示されるので表示。
サービスをクリックして、設定タイムラインを押すことで、イベントの履歴が確認できる。
なお、イベントの履歴は90日間。
脅威検知
脅威インテリジェンス(脅威の防止や検知に利用できる情報の総称)を利用した脅威検知
Amazon GuardDuty:機械学習を用いたクラウドネイティブな脅威検知サービス
悪意あるスキャン(ポートスキャンや総当たり攻撃)、インスタンスへの脅威(C&Cサーバとの通信、アウトバウンドDDos)、アカウントへの脅威(不正なAPIの呼び出し、予期しないリソースアクセス)を検知
検索エリアにGuardと入力し、サービスに移動。
今すぐ始めるをクリックし、右下のGuardDutyの有効化をクリック。
出力されたログの意味は以下で調査可能。
https://docs.aws.amazon.com/guardduty/latest/ug/guardduty_finding-types-ec2.html#backdoor-ec2-denialofservicetcp
ベストプラクティスの確認
AWS Trusted Advisor:AWS環境を自動監視、最適化するための推奨ベストプラクティスを提供。
5つのカテゴリに分類されている(コスト最適化、パフォーマンス、セキュリティ、フォールトトレランス、サービス制限)
検索エリアにTrusted Advisorと入力し、サービスに移動。
プランによって見れる情報の量が違うので注意。
(Businessサポート以上でないと見れないものも多い)
通知設定タブを選択し、毎週Eメール配信をすることが可能。
3:Network編#1
流れの説明
VPC:仮想ネットワーク空間。内部に複数のサブネットを持つことが可能。
将来的な拡張も踏まえて大きく範囲を取ることが必要。
サブネット:VPCの中を細かく分解したネットワーク空間
サブネットはAZ空間(同じリーション内の別データセンター)を跨げない仕様となっている
パブリックサブネット:インターネットゲートウェイ、プライベートサブネットと通信する空間。つまりDMZ。
プライベートサブネット:パブリックサブネットのみと通信できるプライベートな環境。インターネットからは直接アクセスできない。
インターネットゲートウェイ:インターネットと通信するための出入口。VPCごとにアタッチする。パブリックサブネットとインターネットを繋ぐ。冗長化や障害時の復旧が自動的にされるサービスなので、単一障害点では無い。
ここからはAZ空間1aにパブリックサブネットとプライベートサブネットを1つずつ、AZ空間1cにも同様の環境を作成する。
VPCの作成
検索エリアにVPCと入力し、サービスに移動。
VPCウィザードを使えば用意されているテンプレートを使えるため、楽(このハンズオンでは使わない)。
VPCタブで遷移し、VPCの作成をクリックし、名前やCIDRブロック(10.0.0.0/16)を入力し、作成をクリック。
サブネットタブで遷移し、サブネットを作成をクリック。
まず、パブリックサブネットを作成する。
先ほど作ったVPCの選択・サブネット名・AZ(ここでは1aを選択)・CIDR(10.0.1.0/24)の入力を行い、サブネットの作成ボタンをクリック。
同様に同じVPC内にAZを1c、CIDRを10.0.2.0/24にしたものを作成。
次にプライベートサブネットを作成する。
設定はパブリックと同様で、AZ1aの方はCIDRを10.0.11.0/24、AZ1cの方はCIDRを10.0.12.0/24にして作成する。
インターネットゲートウェイタブで遷移し、インターネットゲートウェイの作成をクリック。名前を入力し、インターネットゲートウェイの作成ボタンをクリック。
作ったインターネットゲートウェイを選択し、アクションからVPCにアタッチを選択。
作成したVPCを選択し、インターネットゲートウェイのアタッチボタンを選択。
サブネットのプライベート化とパブリック化
ルートテーブル:各サブネットに1つずつ定義が割り当てられている。ネットワークトラフィックの経路を決定するルートと呼ばれる一連のルールが定義されたテーブル情報であり、各サブネットにルール付けすることで、サブネットの通信経路が決定。つまり、パブリック化・プライベート化することが可能。
ルーティングの優先度は、最も具体的なルートが優先される(最長プレフィックス一致、ロンゲストマッチ)
つまり、10.0.0.0/16と0.0.0.0/0の2つがあれば、10.0.0.0~10.0.255.255以内のIP通信であれば、前者のルート経路が優先される。
この時点では全てのサブネットは1つのルートテーブルのみがアタッチされており、設定がプライベートサブネットになっているため、プライベートサブネットのみにインターネットゲートウェイの経路を追加する。
まずはルートテーブルの作成を選択。VPCは今回作成したものを選択し、作成する。
作成したルートテーブルを開き、ルートタブを押し、ルートの編集を選択。
ルートの追加ボタンを押し、送信先を0.0.0.0/0、ターゲットをInternetGateWay→作成したインテーネットゲートウェイの順番で選択し、ルートの保存を押す。
作成したルートテーブルのサブネットの関連付けタブを押し、関連付けの編集からパブリックのサブネットを選択する。
なお、プライベートサブネットは何も関連付けされていないように見えるが、何も関連付けされていないサブネットに関してはデフォルトのルートテーブル(メインと書かれている)に関連付けされる。
ルートテーブルによる経路設定の理解
まずはEC2にアタッチするIAMを作成する。ロールを選択し、一般的なユースケースの中にEC2があるので、選択する。ポリシーはAmazonSSMFullAccessを選択する。
このSSM=AWS Systems ManagerとはAWSでインフラストラクチャを表示および制御するサービスで、オペレーションの自動化などができる。
次に、EC2を作成する。インスタンスをクリックし、インスタンスの起動を選択。
Amazon Linux2を選択し、ネットワークのVPCを作成したもの、サブネットをパブリックサブネット(1a)にする。
インターネットにWEBサーバは公開するため、自動割り当てパブリックIPは有効にする。
IAMロールは先ほど作成したSSM権限をアタッチ。
ユーザーデータにはインスタンス作成時に実行されるスクリプトを記述できるため、以下の通り入力しておく。
#!/bin/bash
yum -y update
yum -y install httpd
systemctl enable httpd.service
systemctl start httpd.service
これで、*パッケージの更新とhttpdのインストールおよびhttpdの起動とサーバ立ち上げ時にhttpdを起動する設定が行われる。
タグのキーにはName、値にはWEBと入れておく。
セキュリティグループの設定では、インターネットから通信をするので、HTTPを追加しておく。
このハンズオンでは使用しないが、新しいキーペアを作成することで、SSH通信を行うことができる。
なお、上記のキーペアでSSH通信をしたい場合はVPCのDNSホスト名の有効化を有効にする必要がある。
ここまででインスタンスを作成する。
作成したインスタンスの概要を確認し、パブリックIPにアクセスすることでApacheのトップページが表示されればOK。
なお、作成してすぐにアクセスしてもアクセス禁止になることがあるので、少し待ってからアクセスする。
また、ここで公開用ルートテーブルのアタッチからこのEC2のサブネットを外すと、インターネットとの疎通が取れなくなるため、アクセスできなくなることが確認できる。
再度アタッチし直せば当然アクセスできるようになる。
SSMをアタッチしているため、ssh通信をせずとも、インスタンス概要>接続>セッションマネージャー>接続で接続することができる。
(ただし、この通信はSSM自体がVPC外に存在するため、アウトバウンドでインターネット通信が必要であり、インターネットゲートウェイや後述のNATゲートウェイがサブネットのルートテーブルに紐づけられていることが必要)
なお、ssh通信したい場合は、キーペアが保存されたディレクトリで以下のコマンドを実行。
ssh -i キーペア名 ec2-user@パブリック IPv4 DNS
SSHと同じポートでファイル転送したい場合にも以下のようにできる。
scp -i キーペア名 送りたいファイル ec2-user@パブリック IPv4 DNS:/home/ec2-user
もしCloud9が起動しなかった場合はEC2にファイルをおくってハンズオンをする。
なお、MacPCなどで、bad permissionsなどのエラーが出た場合は、キーペアの権限が広すぎるため、以下のコマンドを一度実行する。
chmod 0600 キーペア名
プライベートサブネットからインターネットアクセス
インターネットからプライベートサブネットへのアクセスは遮断したいが、プライベートサブネットからインターネットへのアクセスをしたい場合。
NAT Gatewayを利用する。(NAT instanceは古く今はあまり使われない)
まずはVPCの画面へ移動し、NATゲートウェイタブを選択する。
NATゲートウェイを作成をクリックし、パブリックサブネットの1c側をサブネットにアタッチし、ElasticIPの割り当てボタンをクリックし、NATゲートウェイの作成を行う。
ルートテーブルタブに遷移し、プライベートルートテーブルを開き、ルートタブを選択。
ルートの編集を行い、ルートの追加をクリックした後、送信先を0.0.0.0/0、ターゲットをNAT Gateway→先ほど作成したNAT Gatewayを選択する。
ここでEC2の画面へ移動し、作成を行う。
サブネットはプライベート1cを選択するが、外部へこのサーバは公開しないので、自動割り当てパブリック IPは無効にしておく。
この状態で、セッションマネージャーを使い接続することが可能となる。
また、ルートテーブルからNAT Gatewayへのアウトバウンド通信の定義を削除するとセッションマネージャーを用いた接続が不可となる。
VPC外サービスへの接続方法
ここまではインターネットゲートウェイを使用してSSMへ接続したが、よりセキュアなシステムではプライベートサブネットのみを後世し、VPCからインターネットに接続性を持たせない構成も必要となる。
VPC Endpoint,AWS PrivateLink:VPC内Subnet上で稼働するサービスから、Internet Gateway,NAT Gateway,NATインスタンスを経由せずにVPC外サービスと直接通信させることが可能。
以下の二つの型がある。
Gateway型(Endpoints):S3,DynamoDBとの接続方式
Interface型(AWS PrivateLink):SSM,CloudWatchなどその他サポートされているサービス
今回はSSMへの接続を作成するため、PrivateLinkを作成する。
まずは、インターネットへの接続を削除するために、プライベートサブネット用のルートテーブルからNAT Gatewayへの接続定義を削除する。
VPCの画面からVPCのDNSホスト名の有効化を有効にしておく。
エンドポイントタブを開き、エンドポイントの作成を押す。
まずはサービス名com.amazonaws.ap-northeast-1.ssmを選択し、VPCは今回作成したもの、サブネットはパブリック1cに作成したものを選択する。
セキュリティグループは新規作成を行う。
VPCは今回作成したものを選択し、インバウンドはプライベートサブネットからの通信のみを許可するため、HTTPSで10.0.0.0/16の範囲のものを許可する。
作成したセキュリティグループにチェックを入れ、作成を行う。
もう一度、エンドポイントの作成を行い、com.amazonaws.ap-northeast-1.ssmmessagesを選択した同様のものを作成する。
さらに、com.amazonaws.ap-northeast-1.ssmmessagesを選択したものを作成する。
作成後、使用可能になるまでは数分ほどかかるため待機する。
ここまでで、パブリックサブネット1cにはPrivateLinksのエンドポイントがアタッチされることになり、プライベートサブネット1c内のEC2はパブリックサブネット1cを経由してSSMへアクセスすることになる。
最後に、プライベート1c内に作成したEC2インスタンスにセッションマネージャーで接続できることを確認する。
次にGateway型(Endpoints)を作成してS3に接続する。
EndpointsはVPCにアタッチすることになり、S3に接続するときはVPCから直接接続することになるので、インターネットゲートウェイを経由することはない。
まずはS3でバケットの作成を行う。
S3の画面へ遷移し、バケットを作成を選択。名前のみ入れて作成を行う。
次にIAMの画面へ遷移し、ロールタブを開き、すでに作成したSSMの権限がアタッチされたロールを開く。
ポリシーをアタッチを選択し、AmazonS3ReadOnlyAccessをアタッチすることで、追加で権限をアタッチする。
次にVPCの画面へ遷移し、エンドポイントタブで遷移し、エンドポイントの作成を選択。
com.amazonaws.ap-northeast-1.s3をアタッチする。VPCは作成したものを選択し、ルートテーブルはパブリックのものとプライベートのもの両方を選択する。
(ルートテーブルに経路が登録されていないと接続できないため、この画面で自動でルートテーブルに経路を付与できる。)
ここまで設定し、作成する。ルートテーブルを確認すると、s3への経路も登録されている。
プライベートサブネットのEC2にセッションマネージャーで接続し、以下のコマンドでS3のリスト一覧が出力されればOK。
aws s3 ls --region ap-northeast-1
インターネットを経由しないセキュアな接続ができたことが確認できる。
4:Network編#2
今回はAmazon VPCとオンプレミスの接続を行う。
まず、前提としてVPCはアカウント内で複数作成することができる。
例えば、テスト環境、本番環境のように環境を分けることやシステムごとに環境を分ける際に別VPCを構成して分けることなどができる。
VPC間の接続
VPC間接続する方法は2つある
- VPCピアリング接続を使用する
- Transit Gatewayアタッチメント接続を使用する
VPCピアリングの場合、2つのVPC間をプライベートに接続することとなる。
異なるリージョンや、異なるAWSアカウント間の接続をサポートしている。
前提として、IPアドレス空間が重複していないこと、ピアVPCとピアリングしているVPCと接続することはできない(そのVPCともVPCピアリング接続をする必要があり、接続先が多くなると、ネットワーク構成が複雑になる)。
Transit Gatewayアタッチメント接続の場合、TransitGatewayがネットワークの中央ハブとして各VPCの接続を実現するため、多くのVPCとの接続する場合にネットワーク構成を簡素化することが可能となる。
今回のハンズオンでは前者を利用。
なお、VPCはVPCウィザードでまとめて作成する。
最初はメイン側を作成する。
AZは1aを選択し、CIDRは10.1.0.0/16、サブネットは10.1.0.0/24を入力。
作成後、VPCでフィルタリングにVPC名を入力することで、そのVPCに紐づくリソースのみを表示できる。
ルートテーブルを表示し、インターネットゲートウェイへのルートがある方をパブリック、無い方ををプライベートと名前を変更しておく。
さらにVPCをもう一つ作成する。
次はピアリング側を作成する。
AZは1aを選択し、CIDRは10.2.0.0/16、サブネットは10.2.0.0/24を入力。
同様にルートテーブルの名前は変更する。
ここまでできたら、ピアリング接続タブを選択し、ピアリング接続の作成を選択。
まずは接続元のメイン側のVPCを選択する。
次に、接続先のピアリング側のVPCを選択する。
この画面で、アカウントやリージョンを選択できるが、ここで他のアカウントや他のリージョンなどを指定することが可能となる。
ここまででピアリング接続の作成を選択。
ステータスが承諾の保留中となっているため、アクションからリクエストの承諾を選択し、ステータスがアクティブになる。(まだ接続はできない)
これは、他アカウントと連携する場合などに勝手に接続されないための機能。
次に、ルートテーブルに遷移し、メイン側のパブリックルートテーブルを編集し、
送信先を10.2.0.0/16、ターゲットをPeering Connection→ピアリング側のVPCを選択する。
さらに、ピアリング側のパブリックルートテーブルを編集し、
送信先を10.1.0.0/16、ターゲットをPeering Connection→メイン側のVPCを選択する。
ここまでで接続のための設定が完了したので、疎通確認のためにEC2を作成する。
まずはピアリング側のVPCにEC2インスタンスをプライマリIPを10.2.0.100、セキュリティグループを全てのトラフィックを10.1.0.0/16に対して許可して作成する。
次に検索エリアにCloud9と入力し、サービスに移動する。
(ブラウザのみでコードを記述、実行、デバッグできるクラウドベースのIDEだが、ここは疎通の目的のみで使用する)
create environmentを選択し、VPCはメイン側のVPCを選択し、作成を行う。
ここでコンソールから作成したEC2のインスタンスに対してpingを実行する。
ping 10.2.0.100
PING 10.2.0.100 (10.2.0.100) 56(84) bytes of data.
64 bytes from 10.2.0.100: icmp_seq=1 ttl=255 time=0.406 ms
また、VPCの画面からピアリング接続の画面へ遷移し、アクションからピアリング接続の削除をすることで、pingが通らなくなり、疎通が取れなくなることを確認できる。
再度ピアリングをする場合にはもう一度ピアリング接続の作成とルートテーブルの追加が必要。なお、前のピアリングの設定がルートテーブルに残っているので、削除が必要。
VPCとオンプレミスの接続
用途としては以下のようなものが考えられる。
・オンプレとAWSのハイブリッドな環境を作成するため、セキュアな接続を実現。
・オンプレからAWSにシステム移行するあたり、セキュアにデータ転送を行いたい。
接続方法は以下のようなものがある。
・AWS Site-to-Site VPN:Internet VPN接続。AWS側の***VirtualPrivateGateway(VGW)と顧客側のCustomerGateway(CGW)***を接続する。ユースケースとしては、拠点とAWSを簡単に早く接続したい、少量のトラフィックの送信、価格重視/スモールスタート、バックアップ回線など。暗号化されるが、インターネットを経由するため、通信は安定しないことがある。
・AWS Direct Connect:専用線接続。ユースケースとしては、安定したパフォーマンスが必要、閉域網でも接続が必要、大量のトラフィック送信、主回線、一貫性のある管理の実現。
なお、Site-to-Site VPNを利用する場合には、VPCごとのVPNGatewayが必要となるため、オンプレと直接接続したいVPCがたくさんある場合には、TransitGatewayアタッチメントを利用することで簡易に実現可能。
ここから、オンプレミス想定のVPCを作成し、接続の確認を行う。
なお、ここで作るEC2はオンプレミスのルーター想定として作成する。
VPCウィザードからオンプレ側を作成する。
AZは1aを選択し、CIDRは192.168.0.0/16、サブネットは192.168.0.0/24を入力。
同様にルートテーブルの名前は変更する。
次に、EC2の画面へ移動し、キーペアタブを選択し、キーペアの作成を選択。
インスタンスの作成を選択し、今回はAWS Marketplaceタブをクリックし、CSRと入力し、検索。
Cisco Cloud Services Router (CSR) 1000V - Security Pkg. Max Performanceを選択する。
なお、この製品は30日間FreeTrialで利用できるが、そのあとは値段がかかってしまうため注意。
VPCは先ほど作成したオンプレ側のVPCを選択、プライマルIPは192.168.0.200、キーペアは先ほど作成したものを選択して作成する。
なお、ここでThe seller has not made this product available in the geo location associated with your customer account.と出力され、インスタンスの作成ができなかった。(リージョンは東京リージョンを使用)
推奨ストレージへの変更、再ログインなど試したが失敗となった。
Cisco Cloud Services Router (CSR) 1000V - BYOL for Maximum Performanceを選択し、作成をしたところ正常終了。
(ステータスチェックが初期化から完了までに数分ほど時間がかかる)
なお、ここで作成したMarketPlaceのサブスクリプション削除はAWS Marketplace Subscriptionsから行うため、EC2の削除だけでは消えないため注意*。
次にElasticIPアドレスを作成し、割り当てる。
インスタンス一覧から作成したEC2にチェックを入れ、アクション>ネットワーキング>IPアドレスの管理を選択する。「Elastic IP アドレスを割り当てて」と書いている場所にリンクがあるので、遷移。
Elastic IPアドレスの割り当てボタンを押し、割り当てを選択。
Elastic IPアドレスが追加されるので、チェックを入れたまま、アクション>Elastic IPアドレスの関連付けを選択。
インスタンスは先ほど作成したCSRインスタンス、プライベートIPアドレスは先ほどプライマルIPに入力した192.168.0.200を入力し、関連付けるを押す。
これで作成したCSRのインスタンスを確認したところElasticIPが紐付けられていることが確認できる。
ここでCloud9の画面に移動し、OpenIDEを押す。
FileからUpload local fileを選択し、ダウンロードしていたキーペアをドラッグ&ドロップでアップロード。
現在はキーペアの権限が広すぎるので、以下のコマンドを入力
chmod 400 キーペア名
次に、以下のコマンドでSSH通信ができるかを確認
ssh -i キーペア名 ec2-user@パブリック IPv4 DNS
ログインができればOK(ここはまだパブリックな通信であり、セキュアでは無い。)
VPCの画面へ移動し、仮想プライベートゲートウェイタブを選択し、仮想プライベートゲートウェイの作成を行う。
作成したものにチェックを入れた状態で、アクション>VPCにアタッチを選択。
アタッチする対象はメイン側のVPCを選択。
次にカスタマーゲートウェイタブを選択し、遷移。カスタマーゲートウェイの作成を選択し、ルーティングは動的、IPアドレスはElasticIPとして作成したものを入力し作成。
サイト間のVPN接続タブを選択し、VPN 接続の作成を選択。
Target Gateway TypeはVirtualPrivateGateway、仮想プライベートゲートウェイは先ほど作成した仮想プライベートゲートウェイ、カスタマーゲートウェイは先ほど作成した既存のカスタマーゲートウェイを選択して作成する。
作成されたVPN接続にチェックを入れた状態で設定のダウンロードを選択し、ベンダーをCisco、プラットフォームをCSR AMIを選択し、ダウンロードする。
ダウンロードしたファイルを開き、の部分を全てCSRのIPアドレス(192.168.0.200)に変換する。
ここで再度Cloud9を開き、CSRの仮想マシンにSSH通信をする。
以下のコマンドを入力し、設定モードに移動する。
configure terminal
設定モードに移動したら、変換済みのダウンロードファイルのテキストを全てコピーし貼り付けを行う。
(1行ずつ実行される)
完了後、設定モードからはendで抜けて、以下のコマンドを入力する。
show ip route
Bがついている場所がBGPによって学習した経路
B 10.1.0.0 [20/100] via 169.254.133.73, 00:46:25
10.1.0.0はメインVPCのCIDRと一致している。
以下のコマンドでBGPだけの経路情報も確認できる
show ip bgp
* 10.1.0.0/16 169.254.212.89 200 0 64512 i
*> 169.254.133.73 100 0 64512 i
IPSecのトンネルが2つ張られていることが確認できる。
以下のコマンドで設定を保存する
write memory
VPN接続の画面に遷移し、Tunnel Detailsダブから2つのチャネルが張られていることが確認できる。
ここまででメイン側のVPCの仮想プライベートゲートウェイとオンプレ(CSR)側のカスタマーゲートウェイが接続される。(まだ疎通は取れない)
次に、メイン側のパブリックルートテーブルを開き、ルート伝搬タブを選択、ルート伝達の編集を選択し、チェックを入れて保存。
ルートタブを開くと、VGWのルートが追加されていることが確認できる。
ただし、送信先が0.0.0.0/0になっており、このままでは優先度でインターネットゲートウェイに通信が行ってしまう。なお、この設定はCGWが伝搬したルートがルートテーブルに追加されているので、CGWの設定を変更する必要がある。
ここで再度Cloud9を開き、CSRの仮想マシンにSSH通信をする。
以下のコマンドでBGPだけの経路情報を確認
show ip bgp
Network Next Hop Metric LocPrf Weight Path
*> 0.0.0.0 192.168.0.1 0 32768 i
0.0.0.0 0 i
* 10.1.0.0/16 169.254.212.89 200 0 64512 i
*> 169.254.133.73 100 0 64512 i
伝搬したかった192.168.0.0/16が乗っていないので、ここに設定する必要がある。
次に、以下のコマンドでBGPの設定を確認する。
show running-config | section router bgp
router bgp 65000
bgp log-neighbor-changes
neighbor 169.254.133.73 remote-as 64512
neighbor 169.254.133.73 timers 10 30 30
neighbor 169.254.212.89 remote-as 64512
neighbor 169.254.212.89 timers 10 30 30
!
address-family ipv4
network 0.0.0.0
neighbor 169.254.133.73 activate
neighbor 169.254.133.73 default-originate
neighbor 169.254.133.73 soft-reconfiguration inbound
neighbor 169.254.212.89 activate
neighbor 169.254.212.89 default-originate
neighbor 169.254.212.89 soft-reconfiguration inbound
exit-address-family
上記のnetwork 0.0.0.0とdefault-originateの箇所を削除する必要がある。
まず以下のコマンドで設定モードに移動する。
conf t
階層構造になっているため、1つずつ階層を入力して上がっていく。
ip-192-168-0-200(config)#router bgp 65000
ip-192-168-0-200(config-router)#address-family ipv4
ip-192-168-0-200(config-router-af)#
頭にnoを入れれば設定削除ができるので、以下の通り入力する。
no network 0.0.0.0
no neighbor 169.254.133.73 default-originate
no neighbor 169.254.212.89 default-originate
以下のコマンドで伝搬したいCIDRを設定する。
network 192.168.0.0 mask 255.255.0.0
endで設定モードを抜けて、再度BGPの設定を確認する。
show running-config | section router bgp
router bgp 65000
bgp log-neighbor-changes
neighbor 169.254.133.73 remote-as 64512
neighbor 169.254.133.73 timers 10 30 30
neighbor 169.254.212.89 remote-as 64512
neighbor 169.254.212.89 timers 10 30 30
!
address-family ipv4
network 192.168.0.0 mask 255.255.0.0
neighbor 169.254.133.73 activate
neighbor 169.254.133.73 soft-reconfiguration inbound
neighbor 169.254.212.89 activate
neighbor 169.254.212.89 soft-reconfiguration inbound
exit-address-family
伝搬したい情報が乗っていることが確認できる。
ここで、再度show ip routeで経路情報を確認するが、192.168.0.0/16が存在しないため、ルーティングの登録が必要。
また、以下のコマンドでどんなルート情報があるかを確認できる。
show run | section ip route
ip route 0.0.0.0 0.0.0.0 GigabitEthernet1 192.168.0.1
ip route vrf GS 0.0.0.0 0.0.0.0 GigabitEthernet1 192.168.0.1 global
ここの2行目はデフォルトルートを192.168.0.1(VPC内で動作する内部ルータのアドレス)に送るという設定である
設定モードに再度移動し、以下のコマンドを入力しルーティング設定を追加する。
ip route 192.168.0.0 255.255.0.0 GigabitEthernet1 192.168.0.1
endで設定モードを抜けて、show ip routeで192.168.0.0/16の設定が追加されていることが確認できる。
また、show ip bgpでも192.168.0.0/16の設定が追加されていることが確認できる。
BGPの経路を変更したので、すぐに反映されるために以下の2コマンドを入力する。
clear ip bgp *
write memory
ここまで行うと、メイン側のルートテーブルのルートを見ると、伝搬されたVGWのルートが192.168.0.0/16になっていることを確認できる。
次にオンプレミスのパブリックルートテーブルを開く。
ルートの追加を行い、宛先はメインVPCとなるので、10.1.0.0/16、ターゲットはInstance>CSRを選択する。
次に、EC2の送信元/送信先宛先チェックを無効化する必要がある。
この、送信元/送信先宛先チェックは、デフォルトでEC2インスタンス設定されているが、送信先が指定されていないネットワークトラフィックをインスタンスで処理できるようにする場合は、送信元/送信先チェックを停止する必要があり、ネットワークアドレス変換、ルーティング、またはファイアウォールなどのサービスを実行するインスタンスでは、送信元/送信先チェックを停止することが推奨されている。
EC2画面に遷移し、CSRにチェックを入れ、アクション>ネットワーキング>ソース/宛先チェックを変更を選択。停止にチェックを入れ、保存を選択する。
最後にオンプレ想定VPC内にEC2インスタンスを作成し、疎通の確認を行う。
EC2をオンプレ側のVPCにIPアドレス192.168.0.100、セキュリティグループは全てのトラフィックをメインVPC(10.1.0.0/16)に対して許可して作成する。
ここでCloud9にログインして、以下の通りオンプレ用のEC2に対してpingをする
ping 192.168.0.100
PING 192.168.0.100 (192.168.0.100) 56(84) bytes of data.
64 bytes from 192.168.0.100: icmp_seq=2 ttl=254 time=10.0 ms
確認として、Site-to-Site VPNによって接続していることを確認するために、Site-to-Site VPNの設定を外すと疎通ができなくなることを確認する。
仮想プライベートゲートウェイを開き、アクション>VPCからデタッチを選択する。
再度、Cloud9からPingを飛ばしても疎通が取れないことが確認できる。
再接続するには、まずアクション>VPCにアタッチを選択し、メインVPCにアタッチする。
なお、一度デタッチするとブート伝搬の設定が削除されるため、アタッチした後に再度設定を融合化する必要がある。
メインパブリックルートテーブルのルート伝搬が外れているので、ルート伝搬を開き、設定を有効化する。
ここまで行うと、ルートに経路が再度追加されるため、Cloud9からPingが通るようになる。
5:スケーラブルウェブサイト構築編
VPC作成
VPCウィザードからCIDRを10.4.0.0/16、サブネットのCIDRを10.4.0.0/24、AZを1a(パブリックサブネット1a)で作成する。
次に作成したVPC以下にサブネットを3つ作成(パブリックサブネット1cの10.4.1.0/24とプライベートサブネット1aの10.4.2.0/24とプライベートサブネット1cの10.4.3.0/24)する。
パブリックサブネット1cはインターネットゲートウェイへのルートテーブルがアタッチされていないので、パブリックサブネット1aにアタッチされているルートテーブルをアタッチする。
EC2(Wordpressインストール)の作成
次に、パブリックサブネット1a上にEC2インスタンスを作成する。
なお、自動割り当てパブリックIPは有効にし、ユーザーデータは以下のものを記述する。
#!/bin/bash
yum -y update
amazon-linux-extras install php7.2 -y
yum -y install mysql httpd php-mbstring php-xml
wget http://ja.wordpress.org/latest-ja.tar.gz -P /tmp/
tar zxvf /tmp/latest-ja.tar.gz -C /tmp
cp -r /tmp/wordpress/* /var/www/html/
chown apache:apache -R /var/www/html
systemctl enable httpd.service
systemctl start httpd.service
セキュリティグループはHTTPをソース:任意の場所を選択して追加する。
作成されたサーバにHTTPでアクセスするとWordPressのトップ画面が表示される。
WordPress用のDB(Amazon RDSの作成)
まずはDBが作成するセキュリティグループを作成する。
EC2画面からセキュリティグループタブを選択し、インバウンドにタイプ:MYSQL/Aurora、ソースをカスタムで先ほど作成したWordPressのセキュリティグループに対し許可を入れて作成する。
次にRDSの画面に移動し、サブネットグループタブを選択し、サブネットをプライベートサブネットのもの(10.4.2.0/24と10.4.3.0/24)を選択して作成する。
次にデータベースタブを選択し、MySQLをデフォルトバージョン、VPCは作成したもの、セキュリティグループはRDS用に作成したもの(defaultは消す)、AZは1a、追加設定を開いてDB名を入力し、自動バックアップを無効にして作成する。
DBの作成が完了したらDBを開いてエンドポイントを確認してメモしておく。
ロードバランサーの作成
ロードバランサーはEC2の画面から作成することになる。
EC2の画面へ移動し、ロードバランサータブを選択。
今回はApplication Load Balancerを選択し、AZは作成したパブリック1aと1cの両方をアタッチしする。
セキュリティグループは新規作成(ポート80はデフォルトで空いてるので編集しなくてOK)。
ターゲットの種類は今回EC2インスタンスのロードバランシングをするのでインスタンスを選択し、ヘルスチェックのパスには/wp-includes/images/blank.gifを入力する。
ターゲットの登録では先ほど作成したWordPressをインストールしたEC2インスタンスを選択し、登録済みに追加ボタンを押し、ロードバランサーを作成する。
なお、EC2インスタンスが起動していないと選択肢に出てこないので注意。
状態がActiveになるまで時間がかかるので待機する。
Activeになったら作成したロードバランサーのリスナータブを選択し、デフォルト転送先のリンクを開く。
開いた画面でヘルスチェックの設定が確認でき、ターゲットタブを選択することで、ターゲットがhealthyなのかunhealthyなのか確認できる。
ロードバランサーの画面の説明タブにあるDNS名をブラウザからアクセスし、WordPressのトップ画面が表示できればOK。
WordPressの設定
WordPressのトップがのさぁ始めましょうをクリック。
すでに作成したMySQLのユーザ名、パスワードを入力し、データベースのホスト名にはDBのエンドポイントを入力する。
無事完了しましたと出れば疎通はOK。インストール実行をクリック。
WordPress用の設定を自由に入力し、作成を行う。
作成後、ログインしダッシュボードを作成する。
左上の最初の記事名を選択すると、記事の画面が表示される。
現時点で、冗長構成はまだだが、ロードバランサーを経由して、EC2のWEBページを表示し、RDBにアクセスする構成となっている。
AMIと冗長構成の作成
今回は以下の3つをする。
- AMI(EC2イメージ)の作成
- AMIからEC2を作成
- ロードバランサーで2つのEC2に対し冗長構成を実施。
まずはEC2の画面へ移動し、インスタンスタブを選択し、アクション>イメージとテンプレート>イメージを作成を選択。
名前だけ選択して、作成する。
なお、再起動しないにチェックを入れないので、EC2サーバは再起動がかかる。
EC2の画面からAMIタブを選択し、作成したイメージがあることを確認し、ステータスがavailableになるまで待機。
作成したイメージを選択し、アクション>起動を選択し、パブリックサブネット1cの選択とパブリックIP割り当てにチェックを入れ、(なお、イメージからの作成なので、ユーザーデータにWordPressインストールのためのコマンドは不要)、セキュリティグループはすでに作成したWordPress用EC2サーバのセキュリティグループをアタッチして作成する。
EC2サーバが2台とも起動中になれば、EC2画面のターゲットグループタブを選択し、選択したターゲットグループのターゲットタブを開き、新しいEC2サーバを追加する。
両者のチェックがhealthyになったら冗長構成が完了している。
RDSのマルチAZ化
ここまででEC2はマルチAZ構成となったがRDSはシングルAZ構成となっているので、プライベートサブネット1aのRDSを常時起動のマスターDB、プライベートサブネット1cのRDSを複製系のスレーブDBにする。
RDSの画面を開き、データベースタブを選択し、作成したDBにチェックを入れ、変更ボタンを押す。
マルチAZ配置にチェックを入れ、すぐに適用にチェックを入れて変更を完了する。
ステータスが変更中から利用可能に変わるまでは待機。(10数分かかる)。
終われば、マルチAZのステータスがありになる。
この状態でRDSもマルチAZ構成となる。
ロードバランシングとフェールオーバーの確認
まず、ロードバランシングの確認として、EC2の画面を開き、作成したEC2のどちらかを停止させる。
この状態でWordPressにアクセスしても片方が起動しているので、アクセスできることが確認できる。
RDSの画面を開き、データベースタブを選択し、作成したDBにチェックを入れ、アクション>再起動を選択する。
フェールオーバーで再起動しますかにチェックを入れて再起動をする。
フェールオーバー中はアクセスできないが、完了するとフェールオーバー先にRDSの接続先に切り替わりアクセスができる。
再起動後、通常通りアクセスできることが確認できる。
6:AWS 上で静的な Web サイトを公開しよう!
HTMLやCSSを配置して公開する方法を学ぶ。
S3の静的ホスティング機能を使ったり、CloudFrontを使って画像をキャッシュさせたりする。
Amazon Route53:ドメイン名を数値のIPアドレスに名前解決するDNSサービス。ユーザはドメイン名でサーバにアクセスできるようになる。
Amazon CloudFront:コンテンツのキャッシュをするCDNサービス。WEBサーバのリクエストをキャッシュして保持するため、WEBサーバのアクセス負荷軽減やレスポンス速度向上となる。また、TTL(キャッシュ保持時間)を設定でき、用途に応じてキャッシュ保持の時間を変更できる。
AWS Certificate Manager:SSL証明書の発行と設定をする。ELB,Cloudfrontのみに適用できる。自動更新機能もある。
S3バケット:オブジェクトストレージ。静的コンテンツの配置をして公開することも可能。
S3の静的ホスティング機能
まずはS3バケットを作成する。
なお、バケット名はドメイン名の取得をする場合はドメイン名と同じにしておく必要がある。
今回は公開するので、パブリックアクセスは許可する必要があるため、アクセスブロックのチェックは外す。
作成後、バケットを開き、プロパティタブを開き、静的ウェブサイトホスティングを有効にし、インデックスドキュメントにはindex.htmlを入力。
なお、現時点で、パブリックアクセスになっているわけではない。
アクセス許可タブのバケットポリシーを編集してパブリックアクセスの許可をすることで初めてパブリックアクセスが許可される。
以下のような設定をJSONをバケットポリシーに入力する
説明:https://docs.aws.amazon.com/AmazonS3/latest/dev/access-policy-language-overview.html
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::バケット名/*"
]
}
]
}
次に、index.htmlをアップロードし、プロパティタブの静的ウェブサイトホスティングにあるエンドポイントにアクセスし、正常通り表示できればOK。
Cloud9から開発し、CLIでアップロード
Cloud9の画面を開き、create environmentからデフォルト設定で作成を行う。
なお、構築時にCloud9が何度かデプロイに失敗したため、VPC、インターネットゲートウェイおよびEC2インスタンスを作成しssh通信をして行った。
以下の通りディレクトリ作成する。
mkdir my-webpage
cd my-webpage
aws s3 cp index.html s3://バケット名
なおここでエラーが発生
upload failed: ./index.html to s3://バケット名/index.html An error occurred (AccessDenied) when calling the PutObject operation: Access Denied
PutObjectを以下の通りバケットポリシーに追加することで、エラーが無くなった。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::バケット名/*"
}
]
}
アップロード完了後、バケットウェブサイトエンドポイントでアクセスできればOK。
CSSファイルなどもまとめてアップロードする場合には以下の通りコマンドを実行する
aws s3 cp . s3://バケット名 --recursive
CloudFrontを使った画像キャッシュ
CloudFrontの画面に移動し、Create Distributionをクリックし、Webの方のGet Startedを選択。
Origin Domain NameにS3のバケットウェブサイトエンドポイントを設定して作成。
作成後にGeneralタブのDomain Nameをコピーしてブラウザで開く。
Chromeのデベロッパーツールでネットワークを開き、リロードすることで、リクエストヘッダーにX-Cache: Hit from cloudfrontのような記述があり、キャッシュから取得していることが確認できる。
Route53で独自ドメインを取得して設定
このハンズオンはドメインの1年間の費用がかかるため注意
Route53の画面からドメインの登録ボタンを押す。
取得したいドメイン名を入れてチェックを押すことで、そのドメイン名が取得可能か確認できる。
その後、個人情報を入力して購入する。
メールが届くので、メールを開き、Route53の画面ではステータスの更新ボタンを押し、ステータスに緑のチェックがつく。
ドメインの自動更新もここでONOFFを設定できる。
ここまででドメインの登録が完了でき、保留中のリクエストの一覧にドメインの要求が記録され、15分くらい経つと、登録済みドメインに登録がされる。
ホストゾーンタブを開き、ドメイン名を選択、レコードセットの作成を選択し、エイリアス名にS3のバケットウェブサイトエンドポイントを設定する。
取得したドメインでアクセスすることで、ページが表示できる。
ACMを使ってHTTPSでアクセスする
ここでRoute53のエンドポイントはCloudFrontに設定し、
証明書はCloudFrontにインポートする。
また、S3のバケットに直接アクセス禁止し、CloudFrontでしかアクセスできないようにする。
まずは検索ボックスにACMと入力し、AWS Certificate Managerの画面に移動する。
なお、証明書はヴァージニア州で作成しないと使えないので必ずリージョンは変更する
証明書のプロビジョニングで今すぐ始めるを選択し、証明書のリクエストを押す。
ドメイン名にRoute53で取得したドメイン名、検証方法はDNSを選択する。
ステップ 5: 検証ではドメイン名を開き、レコードの作成ボタンを押し、CNAMEレコードを作成する。
最後に続行ボタンを押し、作成をする。
CloudFrontの画面に移動し、作成したリソースを開き、Behaviorsタブを選択し、Editボタンを押す。
Redirect HTTP to HTTPSにチェックを入れることでHTTPリクエストを強制的にHTTPSリクエストにリダイレクトさせることが可能。
次にGenaralタブを選択し、Editを押し、Alternate Domain Names(CNAMEs)に、Route53で取得したドメイン名を入力し、Custom SSL Certificate (example.com)にチェックを入れ、先ほど作成した証明書を選択する。
ここまでで証明書がCloudFrontにインポートされる。
次にRoute53の画面に移動し、エンドポイントにはCloudFrontを選択する。
全てのアタッチが完了した後にアクセスすることで、HTTPSでアクセスできることになる。また、HTTPはHTTPSにリダイレクトされる。
次に、S3への直接アクセスを抑止する。
まずS3のバケットポリシーを削除し、静的ウェブサイトホスティングも無効にする。
この時点でS3への直接アクセスはできない。
CloudFrontを開き、Origins and Origin Groupsタブを開き、Editを選択。
すでにあるバケットウェブサイトエンドポイントは削除し、プルダウンからS3リソースを選択する。
選択肢が追加されるので、Restrict Bucket Access(ユーザ自身の代わりにオリジンアクセスアイデンティティに設定された権限によりS3にアクセスできる。また、署名付きURLのアクセスのみ許可される)とGrant Read Permissions on Bucket(S3 bucket policyに自動でAccess Identityを追記する)をオンにする。
これにより、CloudFront経由のみのアクセスしかできなくなる。
7:監視編 サーバーのモニタリングの基本を学ぼう
サーバー、DBのモニタリングを行う。
モニタリングはシステムのリソース不足、アプリケーションの稼働を確認し、ユーザ体験を損なわないために行う。
インフラ担当者は割り当てているリソース量に過不足が無いか、不正なアクセスや操作が発生していないか
開発者はサービスは適切な応答をしているか、アプリケーションの品質を改善したい
という思いのもとモニタリングを行う。
今回はCPUのパフォーマンスやDiskのキャパシティ等のリソース監視や各サービスのログ監視を行う。
AWS X-Ray:トレース(アプリケーションやサービスの実行状況)を監視する。エラーの原因解明などに使う。
Amazon CloudWatch:ログとメトリクス(CPUパフォーマンス等)を監視する。モニタリングに関する様々な機能を所持しており、各種サービスはメトリクスをCloudWatch Metricsに送信し、CloudWatch Alarmsでメトリクス(つまりある閾値を超過するかどうか)に応じたアクションを実行する。なお、CloudWatch Eventsでは、イベント(状態の変化など)に応じて「Lambda関数の実行」、「SNSでメール通知」、「Kinesisストリーム」、「SQSキュー」などの実行ができる。
CloudWatch Logsはログを収集し、CloudWatch Log Insightsで可視化する。
CloudWatch Dashboardsではメトリクスとログなどを一覧で自由にカスタマイズして確認することができる。
5:スケーラブルウェブサイト構築編で作成したものと同じ構成を実装し監視する。
また、この環境はCloudFormationというサービスを利用して作成する。
CloudFormation:テキストファイル(テンプレート)を使用して、AWSリソースを環境構築するサービス。
詳細はハンズオン12で行う。
環境の作成
CloudFormationの画面に移動し、スタックの作成を選択。
このハンズオンでは事前ダウンロードしたmonitoring-1.yamlというファイルを使う。(内容は割愛)
完了まで10分ほどかかる。
作成したら出力タブへ遷移し、2つのEC2DNS名にアクセスする。
WordPressの初期設定は動画に従い入力する。
メトリクスの確認
CloudWatchを表示し、メトリクスタブを開く。
EC2>インスタンス別メトリクスを開く。
検索ボックスにCPUと入力し、表示されたものの中でにチェックを入れるとグラフで確認できる。
また、上部の時間を選択すると、間隔の時間を選択できる。カスタムで自由な時間間隔のメトリクスも確認できる。
また、ApplicationELB>AppELB別、TG別メトリクスを選択すると、ELBのメトリクスを確認できる。
次に、RDS>データベース別メトリクスを選択して、RDSのメトリクスも確認できる。
グラフ化したメトリクスタブを開いて、期間を変更するとグラフの表示間隔の時間を編集することもできる。
グラフのオプションタブを開いて、円形、棒線などグラフの表示の仕方を変更することも可能。
CWAgent>ImageId,InstanceId,InstanceType,device,fstype,pathを開いて、メトリクスがdisk_used_percent、パスが/のものを開くとディスク使用率が確認できる。
CWAgent>ImageId,InstanceId,InstanceTypeを開いて、メトリクスがmem_used_percentのものを開くと、メモリ使用率が確認できる。
アラートの使用
アラートは例えば50%以上ディスク使用率が上がった場合に管理者に通知を送るときなどに利用する。
CloudWatch Metricsの閾値をディスク使用率を設定してCloudWatch AlarmsでSNSのアクションを実行し、Lambdaを実行することなどができる。
今回は、CloudWatch Alarmsでメールを送信する。
Amazon SNS:特定のサービスにメッセージを送信するためのサービス。Amazon SQS、AWS Lambda、HTTP、HTTPS、Eメール、SMSなどで受け取れる。
CloudWatch画面からアラームタブを選択し、アラームの作成をクリック。
CWAgent>ImageId,InstanceId,InstanceType,device,fstype,pathを開いて、メトリクスがdisk_used_percent、パスが/のものを選択する。
アラームの条件を90%以上にする。
トリガーは通知にアラーム状態(メトリクスまたは式が定義したしきい値の範囲外にある時)を選択し、メールアドレスを入力し、アラームを作成する。
通知:メールなどによって管理者に通知を行う。
AutoScalingアクション:オートスケールを実施する。なお、事前にAutoScalingグループの作成をしておくことが必要
EC2アクション:EC2の削除や再起動を行う。
作成後、確認メールが届くので開いて紐付けを完了する。
ログの確認
CloudWatchLogには階層がある
ロググループ:複数のログストリームで構成。一般的にはアプリケーションの単位(WEBServerなど)で集約。
ログストリーム:複数のログイベントで構成。一般的にはリソースの単位(インスタンスごと)で集約
ログイベント:実際のアプリケーションログ
CloudWatchを表示し、ログタブを開く。
View log groupを選択し、ロググループの一覧が表示される。(すでにCloudFormationで作成されている)
保持を失効しないから変更することでログの保存期間も変更できる。
ロググループを開いて、ログストリームからログが確認できる。
フィルターにGETなどを入れてフィルタリングをすることなどが可能。
ハンズオンでは省略したが、CloudWatchグループを作成してEC2からログを収集するにはCloudWatchエージェントのインストールなどが必要。
参照:https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/Install-CloudWatch-Agent.html
ログ分析
ログ分析はアクセスログやエラーログの解析によりビジネス、アプリケーションの改善のために行う。
ここではCloudWatch Log Insightsでログを検索して分析する。
これはクエリ構文を利用してログの分析を行う。
構文:https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/logs/CWL_QuerySyntax.html
CloudWatchを表示し、インサイトタブを開く。
ロググループを選択し、クエリはデフォルトのままクエリ実行をするだけでもログイン数を確認できる。
また、右側にサンプルのクエリがあるため、それを選択し利用することもできる。
今回はクエリに以下のものを入力する
parse '* - * [*] "* * *" * * * *' as host, identity, dateTimeString, httpVerb, url, protocol, statusCode, bytes, referrer, userAgent
| sort maxBytes desc
次に400番台のエラーを確認するクエリを以下の通り実行する
parse '* - * [*] "* * *" * * * *' as host, identity, dateTimeString, httpVerb, url, protocol, statusCode, bytes, referrer, userAgent
| sort maxBytes desc
| filter statusCode like /(4\d\d)/
なお、この分析の結果はダッシュボードに表示したり、エクスポートしたりすることができる。
WordPressの監視
ダッシュボードは1つのサービス、1つのプロダクトのステータスを効率的に確認できるため、必要。
Automatic DashboardではAWSが推奨するベストプラクティスに基づいたダッシュボードが作成できる。
CloudWatchを表示し、ダッシュボードタブを開く。
線、メトリクスを選択して作成し、EC2から2つのWebサーバのCPUUtilizationにチェックを入れ、ウィジェットの作成をする。
さらにウィジェットの追加を押し、テキストを選択し、MarkDownを編集し、メモや実行ボタンを作成できる。
次にウィジェットの追加を押し、ログテーブルを選択し、グループからアクセスログを選択することで、ログ一覧を表示させることができる。
最後にダッシュボードの保存を押す。
また、CloudWatchトップにあるCloudWatchタブを押して概要からEC2を選択することで、EC2全体のログを確認できる。
さらにすべてのリソースと書かれているドロップダウンリストからリソースグループの作成を選択し、CloudFormation スタックベースにチェックを入れ、CloudFormation スタックに作成したCloudFormationを選択することでリソースグループの作成ができる。
これを作成した後にドロップダウンからリソースグループを選択することで、特定リソースグループの監視ができる。
EC2停止時に通知
CloudWatchEventsでイベントをトリガーにアクションを実行する。
今回はアクションでSNSを実行してメールを送信する。
CloudWatchを表示し、イベントタブを開く。
今すぐ始めるを選択し、
イベントソースは***イベントパターンで(スケジュールなども可能)***EC2 Instance State-change NotificationがStoppedの時を選択する。
ターゲットはSNSトピックをCloudWatchAlarm作成時に作成したトピックを選択して作成する。
この状態でEC2を停止させると通知が飛ぶ。
8:サーバーレスアーキテクチャで翻訳 Web API を構築する
サーバレスアーキテクチャ:インフラの管理や運用が不要で自動でスケールし、高い可用性を持ったリクエストの従量課金制のサービス。EC2に比べて自由度は少ないが、管理の手間は少ない。
Amazon API Gateway:サーバを構築、管理することなくAPIを作成、管理するサービス。可用性、スケーリング、APIキー管理などのAPI開発で必要なことを一任し、開発者はビジネスの差別化に繋がる作業に中中できる。REST APIとWebSocketに対応している。APIなのでリソース×メソッドの組み合わせでフローを定義する。フローにはメソッドリクエスト、統合リクエスト、統合バックエンド、統合レスポンス、メソッドレスポンスがある。設定はリソースとメソッドごとに定義を行い、APIごとにデプロイする。また、ステージを作成してそのステージのみにデプロイ可能(本番用と開発用を分けれる)。その他、バージョニングやログ収集、モニタリングが可能。
メソッドリクエストでは、リクエストの受付として認証や受け付けるパラメータ、必須HTTPヘッダなどを設定できる。
統合リクエストでは、統合バックエンドで何を使用するか(LambdaやHTTP,Mock、AWSサービスなど)を指定できる。リクエストの変換(XMLをJSONにするなど)も可能、プロキシ統合で変換せずにスルーできる。
統合レスポンスでは、レスポンスの変換(XMLをJSONにするなど)も可能、プロキシ統合で変換せずにスルーできる
メソッドレスポンスでは、リクエストに対する最終的なAPI Gatewayとしてのレスポンスに関する設定(ステータスコードやHTTPレスポンスヘッダなど)ができる。
AWS Lambda:サーバレスのサービスであり、開発者はコードの記述に集中できる。実行回数や実行時間で課金がされる。対応している言語はいくつかあり、サポートされていない言語はカスタムランタイムを実装して利用する。最初に呼び出される関数はハンドラで指定する。設定できる項目としては確保するメモリの量(CPUはメモリ量に比例する)、タイムアウト値、実行IAMロール(例えばDynamoDBへの書き込み権限など)がある。呼び出し方式としては非同期型(例えば、S3へのファイル格納を契機にLambdaが呼び出され、Lambdaへのリクエストが正常に受付けられたかどうかのみ返却する)や同期型(API Gatewayなどを通じて、Lambdaにリクエストが飛び、レスポンスを返却する)がある。Lambdaはコンテナ上で動作し、1つのコンテナでは1つの1つのリクエストまでを受け付ける。コンテナは再利用される(ウォームスタート)が、利用できるコンテナがない場合新しいコンテナを起動して実行する(コールドスタート)。
連携パターンとしては、以下のものがある。
- Lambda関数を同期的に呼び出す(API GatewayからLambdaを呼び出し)。関数の実行が終わるのを待つ必要があり、実行結果が返される。
- Lambda関数を非同期的に呼び出す(S3のファイル格納などを契機にLambdaが呼び出される)。実行が終わるのを待つ必要がない代わりに実行結果は返されない。
- Lambdaがストリームベースでイベントを読み取る(DynamoDBへのデータ格納をLambdaが検知し、実行する)。新しいデータが無いかをポーリングしてあれば処理を実行する。
- Lambdaがストリームベースでなくイベントを読み取る(SQSへのデータ格納をLambdaが検知し、実行する)。新しいデータが無いかをポーリングしてあれば処理を実行する。
上記の分類は以下の通りになる
ポーリングベース:Lambdaがポーリングして、データがあれば関数を実行
1. ストリームベース(同期呼び出し)→上記の3
2. ストリームベースではない(同期呼び出し)→上記の4
ポーリングベースでない:Lambdaはイベントソースから呼ばれる
1. 同期呼び出しタイプ→上記の1
2. 非同期呼び出しタイプ→上記の2
*** Amazon S3***:高い耐久性(99.999999999%)をもち、3つのAZに跨ってデータ格納される。容量も無制限で、静的WEBホスティング機能もある。
Amazon DynamoDB:フルマネージド型のNoSQL。3つのAZに保存されるため信頼性が高く、ストレージの容量制限が無い。また、性能要件に応じてテーブルごとにキャパシティを定義できる。オートスケールも可能。テーブルには一意のプライマリキーがある(パーティションキーもしくはパーティションキーとソートキーの組み合わせ)。
なお、ソートキー以外に絞り込み検索を行うKeyを持つことができるローカルセカンダリーインデックス(あるテーブルをベースに、パーティションキーはそのままに、異なるソートキーのテーブルを作成する仕組み)やパーティションキーの代わりに検索を行うためのグローバルセカンダリーインデックス(あるテーブルをベースに、異なるパーティションキー・ソートキーのテーブルを作成する仕組み)を持つことができる。
キャパシティユニットは1ユニットにつき最大4KBのデータを1秒に1回読み込み可能で、1ユニットにつき最大1KBのデータを1秒に1回書き込み可能。
Amazon Translate:翻訳サービス
開発者ガイド:https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/welcome.html
APIリファレンス:https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/index.html
今回のハンズオンではAPI Gatewayを経由してLambdaを呼び出し、Lambda上で動くコードがTranslateを呼び出し翻訳結果を取得し、結果をレスポンスとして返す。また、その翻訳結果をDynamoDBに格納する。
Lambdaの作成
Lambdaの画面に移動し、関数の作成ボタンを押す。
ランタイムはPython3.7で作成を行う。
下にスクロールし、基本設定を編集することで、メモリや実行時間、IAMロールを変更することが可能。
基本設定からIAMロールを開くと、権限としてCloudWatch Logsが割り当てられていることなどが確認できる。
右上のテストボタンではテストを作成でき、ドロップダウンから作成したテストを選択してテストボタンを押すことでテストができる。
ハンズオン用のコードを貼り付け、デプロイで保存ができ、テストでデプロイ後のコードを実行できる。
logger.info(event)でログを出力しているので、コンソールにFunction logs:以下にログが出力される。
また、上部にあるモニタリングタブを開き、CloudWatch のログを表示を押し、貯まったログを確認することができる。
translateの利用
まずはハンズオン通りにコードを変更する。
ポリシーを開き、TranslateFullAccessをアタッチして実行(本来は権限は絞る)すると、翻訳結果がコンソール出力される。
API Gatewayの作成-Mock
最初にMockでAPI Gatewayを作成する。
API Gatewayの画面に移動し、APIを作成を押す。
RESTを選択し、名前だけ入れて作成する。
アクションからリソースの作成を選択し、名前を入れて作成する。
次にアクションからメソッドの作成を選択し、GETを選択する。
一旦統合タイプはMockを選択する。
統合レスポンスを開き、三角ボタンを押し、マッピングテンプレートのapplication/jsonをクリックし、以下のようなJSONを定義する。
{
"statusCode": 200,
"body": {
{
"report_id": 5,
"report_title" : "Hello, world"
},
{
"report_id": 7,
"report_title" : "Good morning!"
}
}
}
次にフロー画面に移動し、テストボタンでテストを実行し、上記のJSON結果が返ることを確認する。
次にアクションからAPIのデプロイを選択し、新しいステージでDEV等を入れて作成をする。
ステージタブを開き、DEV>/>/handsonrs>GETを開き、URL の呼び出しに記述されているURLを開くとMockのAPIのレスポンスが返却される。
このように、バックエンドの開発が終わってなくてもモックのAPIを作成することで、効率的にフロントエンドの開発をすることができる。
API Gatewayの作成-Lambda
まず、前回作成したMock呼び出しのリソースをアクションから削除する。
アクションからリソースの作成を選択し、名前を入れて作成する。
次にアクションからメソッドの作成を選択し、GETを選択する。
統合タイプはLambdaを選択し、プロキシ統合にはチェックを入れてに、関数は最初に作ったものを選択する。
プロキシ統合にチェックを入れたため、統合レスポンスは変換できずにパススルーとなる。
ここをプロキシ統合にチェックを入れないと以下の通りエラーになってしまうので注意。
{"errorMessage": "'queryStringParameters'", "errorType": "KeyError", "stackTrace": [" File \"/var/task/lambda_function.py\", line 8, in lambda_handler\n input_text = event['queryStringParameters']['input_text']\n"]}
まず、メソッドリクエストを開いて、URL クエリ文字列パラメータにinput_textを必須で保存する。
Lambdaを開いてコードを新しいものに編集する。
設定されたクエリ文字列パラメータは以下のようにして取得できる。
input_text = event['queryStringParameters']['input_text']
なお、返却するJsonにはheaderとisBase64Encodedが必要となる。
統合レスポンスドキュメント:https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/api-gateway-integration-settings-integration-response.html
新しいテストをテストテンプレートAmazon API Gateway AWS Proxyにして、queryStringParametersの中身を以下の通り変更する。
"queryStringParameters": {
"input_text": "おやすみ"
},
次にアクションからAPIのデプロイを選択し、新しいステージでDEV等を入れて作成をする。
ステージタブを開き、DEV>/>/handsonrs>GETを開き、URL の呼び出しに記述されているURLを開き、末尾にクエリパラメータを渡す(?input_text=おやすみ)とAPIのレスポンスが返却される。
DynamoDBの作成
DynamoDBの画面に移動し、テーブルの作成を押す。
テーブル名をtranslate-history、パーティションキーをtimestamp、デフォルト設定の使用をチェック外して、キャパシティは読み込みも書き込みも1にして作成する。
作成した後に、項目タブを開き、項目の作成から項目を追加することが可能。
コードをハンズオンにしたがって修正し、IAMにAmazonDynamoDBFullAccessを追加する。
(本来は権限は絞る)
テスト、およびURLでのアクセスが成功すればOK。
9:AWS SAM を使ってテンプレートからサーバーレスな環境を構築する
今回はまず、前回作成したような環境をAWS SAMでテンプレートから作成する。
AWS SAM:サーバレスアプリケーション構築用のオープンソースフレームワーク。CloudFormationより簡潔に記述できる。テンプレートを記述してパッケージングしてデプロイする。
使い方は以下の順序で行う。
- SAMテンプレートを記述
- パッケージングする
- デプロイする
SAMプロパティのリファレンス:https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/sam-specification-resources-and-properties.html
開発環境の構築
まずはCloud9を構築する。
AWS Resourcesを押し、Lamdbaファンクションのマークを選択して新規作成画面を開く。
ランタイムをPython3.6を選択して他はデフォルトで作成する。
作成が完了したら、Lambdaの画面にもLambdaが追加される。
ソースを編集してRUNボタンを押すとソースを実行できる。
また、Lambdaファンクションボタンを選択して、↑ボタンを押すとデプロイすることができる。
SAMでLambdaを作成
まずは以下の通りs3バケットを作成する。
aws s3 mb s3://バケット名
なお、バケット名の命名規則に誤りがあると以下の通りエラーが起こる。
make_bucket failed: s3://誤りのあるバケット名 An error occurred (InvalidBucketName) when calling the CreateBucket operation: The specified bucket is not valid.
コマンドでディレクトリとpyファイル、yamlファイルを作成する。
mkdir 作業ディレクトリ
cd 作業ディレクトリ
mkdir スクリプトディレクトリ
touch スクリプトディレクトリ/pyファイル
touch yamlファイル
pyファイルはハンズオンを参考に編集する
yamlファイル(SAMテンプレート)を以下のように編集する
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: 説明
Resources:
TranslateLambda:
Type: AWS::Serverless::Function
Properties:
FunctionName: 関数名
CodeUri: ./スクリプトディレクトリ
Handler: translate-function.lambda_handler
Runtime: python3.7
Timeout: 5
MemorySize: 256
以下のコマンドでパッケージングする(ファイルはS3に格納される)
aws cloudformation package \
--template-file yamlファイル \
--s3-bucket バケット名 \
--output-template-file パッケージしたyamlファイル
以下のコマンドでデプロイする
aws cloudformation deploy \
--template-file ./パッケージしたyamlファイル \
--stack-name CloudFormationのスタック名 \
--capabilities CAPABILITY_IAM
なお、このコマンドでエラーが表示された
Failed to create/update the stack. Run the following command
to fetch the list of events leading up to the failure
aws cloudformation describe-stack-events --stack-name CloudFormationのスタック名
このスタックを確認すると以下のエラーが表示されていた
API: iam:CreateRole User: ユーザ名/AWSCLI is not authorized to perform: iam:CreateRole on resource:
EC2のユーザにはPowerUserAccess権限を付与しているが、IAMのアクションが実行できない権限であるため、IAMFullAccessをアタッチし作成済みのスタックは消して、再度実行することでエラーは解決した。
SAMでTranslateとの連携を作成
次にAmazon Translateをソース中で呼び出すために、
ハンズオン通りにpyファイルを新たに書き換える。
yamlファイルも以下の通り書き換える。
ここに書いているように、アタッチする権限はPolicies以下に記述する。
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: 説明
Resources:
TranslateLambda:
Type: AWS::Serverless::Function
Properties:
FunctionName: 関数名
CodeUri: ./スクリプトディレクトリ
Handler: translate-function.lambda_handler
Runtime: python3.7
Timeout: 5
MemorySize: 256
Policies:
- TranslateFullAccess
再度、コマンドでパッケージングとビルドを行い、Lambdaが更新されていればOK。
SAMでAPI Gatewayとの連携を作成
ソースをハンズオンの通りに編集する。
yamlを開き、以下の通り編集する。
ここで、Event以下にどのリクエストでLambdaにアクセスするかを記述する。
なお、呼び出し元のAPIGatewayは!Refで参照を行っている。
その下で、作成するAPIGatewayを作成している。
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: 説明
Resources:
TranslateLambda:
Type: AWS::Serverless::Function
Properties:
FunctionName: 関数名
CodeUri: ./スクリプトディレクトリ
Handler: translate-function.lambda_handler
Runtime: python3.7
Timeout: 5
MemorySize: 256
Policies:
- TranslateFullAccess
Events:
GetApi:
Type: Api
Properties:
Path: /translate
Method: get
RestApiId: !Ref TranslateAPI
TranslateAPI:
Type: AWS::Serverless::Api
Properties:
Name: translate-api-2
StageName: dev
EndpointConfiguration: REGIONAL
SAMでDynamoDBとの連携を作成
ソースをハンズオンの通りに編集する。
yamlを開き、以下の通り編集する。
ポリシーにはAmazonDynamoDBFullAccessを追加でアタッチしている。
また、作成するDynamoDBを作成する記述も追加している。
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: 説明
Resources:
TranslateLambda:
Type: AWS::Serverless::Function
Properties:
FunctionName: 関数名
CodeUri: ./スクリプトディレクトリ
Handler: translate-function.lambda_handler
Runtime: python3.7
Timeout: 5
MemorySize: 256
Policies:
- TranslateFullAccess
- AmazonDynamoDBFullAccess
Events:
GetApi:
Type: Api
Properties:
Path: /translate
Method: get
RestApiId: !Ref TranslateAPI
TranslateAPI:
Type: AWS::Serverless::Api
Properties:
Name: translate-api-2
StageName: dev
EndpointConfiguration: REGIONAL
TranslateDynamoDbTbl:
Type: AWS::Serverless::SimpleTable
Properties:
TableName: translate-history-2
PrimaryKey:
Name: timestamp
Type: String
ProvisionedThroughput:
ReadCapacityUnits: 1
WriteCapacityUnits: 1
SAM CLIの利用
SAM CLI:AWS SAMをローカルで使用する上で様々な機能を提供するCLI。要Dockerインストール。2020/07よりメジャーアップデート。(ハンズオンの動画時点ではベータ版)
以下のようなコマンドがある。
sam init:テンプレートを使ってサーバレスアプリケーションを対話形式で初期化
sam build:ローカル環境でビルド
sam deploy --guided:AWS環境へデプロイ
sam validate:SAMテンプレートの事前検証
sam local start-lambda / start-api:LambdaローカルエンドポイントやAPIエンドポイントを起動し、実行のテストが可能
以下のマニュアルを確認してインストールを実行
SAM CLIインストール:https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/serverless-sam-cli-install-linux.html
Dockerインストールして、その後インスタンスを再起動
sudo yum update -y
sudo amazon-linux-extras install docker
Dockerを起動
sudo service docker start
sudo usermod -a -G docker ec2-user
docker ps
gitのインストール
sudo yum install git
Homebrewのインストール。
なお、現時点のHomebrewインストールでは通常ec2-userのパスワードを聞かれるが、Ctrl+Dを押して、パスワードの入力を回避する。
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
パスの追加
test -d ~/.linuxbrew && eval $(~/.linuxbrew/bin/brew shellenv)
test -d /home/linuxbrew/.linuxbrew && eval $(/home/linuxbrew/.linuxbrew/bin/brew shellenv)
test -r ~/.bash_profile && echo "eval \$($(brew --prefix)/bin/brew shellenv)" >>~/.bash_profile
echo "eval \$($(brew --prefix)/bin/brew shellenv)" >>~/.profile
インストールされていることの確認
brew --version
SAM CLIのインストール
brew tap aws/tap
brew install aws-sam-cli
インストールの検証
sam --version
プロジェクトの作成をする。
テンプレートはQuick start、ランタイムはPython3.7、サンプルはHello World Exampleを選択して作成。
sam init
検証およびビルドを行う
sam validate
sam build
デプロイを行う。
リージョンは東京にして、
変更点を確認するか、IAMを作成するか、CLIでのやりとりをyamlに保存するかを聞かれるので全部yesを選択する。
sam deploy --guided
なお、ローカルでテストしたい場合は以下の通り起動する
sam local start-lambda
別ターミナルを開くなどして、起動したLambdaにむけて通信のテストを実行する。
curl http://127.0.0.1:3000/hello
10:AWS Lambda と AWS AI Services を組み合わせて作る音声文字起こし & 感情分析パイプライン
S3トリガーで実行する
まずはS3バケットを作成する。
次にLambdaの画面に移動し、関数の作成を選択する。
設計図の使用にチェックを入れ、s3-get-object-pythonを選択する。
S3バケットは先ほど作成したものを選択し、全てのオブジェクト作成イベントをイベントに設定して作成する。(現在はトリガー有効化チェックは無かったため、次の手順で行う)
関数が作成されたら、デザイナーのS3を開いて、有効化にチェックを入れる。
ファイルをS3に格納すると、CloudWatchにログが格納されており、Lambdaが起動したことを確認できる。
このフォルダに、ハンズオンでDLした音声ファイルも格納しておく。
Amazon Transcribeを使った文字起こし
Amazon Transcribe:音声をテキストに変換する文字起こしサービス
まずはLambdaを経由せずTranscribeのみを使ってみる。
Transcribeで文字起こしした文字を格納するS3を作成する。
Amazon Transcribeの画面を開いて、Transcription jobsタブを開き、Create jobを選択する。
言語はJapaneseを選択し、input側を最初に作成したS3バケットとそこに格納した音声ファイル、output側をCustomer specified S3 bucketにチェックを入れ、結果格納先のS3バケットを選択して作成する。
ステータスがCompleteになった後に、格納先のS3バケットを見れば、jsonの中身に文字起こしの結果が格納されていることが確認できる。
Amazon TranscribeとLambdaの連携
まず、Lambdaを開いて、IAMを表示し、AmazonTranscribeFullAccessとAmazonS3FullAccessを追加する。
ソースコードはハンズオンのソースコード通りに変更し、デプロイを押す。(格納先のS3は自分で作ったものに変更する)
再度、トリガーのS3に音声ファイルをアップロードすると、Lambdaが実行され、Transcription jobsにジョブが追加される。
完了後、結果格納先のS3に文字起こし結果のjsonが格納される。
文字起こししたテキストをComprehendで感情分析
Amazon Comprehend:機械学習を使用した自然言語処理サービス。キーフレーズやエンティティ(場所、日付)の取得、感情分析ができる
先ほど作った結果格納先のS3に文字起こしファイルが格納されたのを契機にLambdaを起動させて、Comprehendを呼び出して結果を表示する。
まずはComprehendの動きを確認する。
Amazon Comprehendの画面を開いて、Launch Amazon Comprehendを選択する。
何か文字を入れて、analyzeボタンを押すことで、分析することができる。
次にLambdaの画面に移動する。
設計図の使用にチェックを入れ、s3-get-object-pythonを選択する。
S3バケットはTranscribe結果格納用のバケットを選択し、全てのオブジェクト作成イベントをイベントに設定し、jsonファイルが格納された時のみ動作させていため、サフィックスに.jsonを入力して作成する。
関数が作成されたら、デザイナーのS3を開いて、有効化にチェックを入れる。
IAMを開いて、ComprehendFullAccessとAmazonS3FullAccessを追加する。
ソースコードはハンズオンのソースコード通りに変更し、デプロイを押す。
再度、音声ファイルを最初に作った音声ファイル格納用のS3に格納して、数秒後にCloudWatchを開くと、感情分析したログが表示されていることが確認できる。
Amazon Pollyで作成した音声ファイルをパイプラインに投入する
Amazon Polly:テキストを音声に変換するサービス。
今回はPollyで作成したテキストの音声データを最初に作成した音声ファイル格納用のS3に格納して、パイプラインを流す。
Amazon Pollyを開いて今すぐ始めるボタンを押す。
テキストを入力して、S3に向けて合成ボタンを押す。
S3 出力バケットに作成した音声ファイル格納用のS3の名前を入力して合成する。
タスクIDのリンクを押して遷移し、ステータスが完了になれば、パイプラインが実行される。
CloudWatchのログを確認して実行されていればOK。
11:CloudEndure Migrationを使ってオンプレミスサーバーをAmazon EC2に移行する
クラウド移行への道のりは2種類ある
- クラウドネイティブ:当初からクラウドに最適化した設計を行い、クラウド最適化したアプリ開発を行う。
- リフト&シフト→クラウド最適化:当初はハード老朽化やコスト削減目的でクラウドへ単純移行し、移行した後でクラウド最適化させる。
CloudEndure Migration:オンプレのマシン上にインストールしてサーバ移行をするエージェント型サーバ移行サービス。物理、仮想マシン問わない。管理コンソールはSaaS上にある。
CloudEndureエージェントがインストールされたオンプレ環境、移行先のAWS環境(移行先のサーバはCloudEndureが自動生成する)、オンプレとAWSを繋ぐ回線(VPN or Direct Connect、Port:1500 暗号化済み)、CloudEndureのSaaSサービスのアカウントが必要。
流れは以下のように実施する。
- CloudEndure用IAMユーザを作成し、CloudEndure Consoleから認証
- 移行対象ソースマシンにCloudEndure Agentをインストール
- オンプレからデータを非同期で転送する
- ステージング領域にレプリケーションサーバが作成され、データをEBSにレプリケーション
- カットオーバーを実行し、ステージングEBSからsnapshotが作成され、コンバーターインスタンスにアタッチ->変換->本番用のターゲットEC2インスタンスにアタッチ。
- コンバーターインスタンスでは、適切なAWSドライバの挿入、ブートローダーの適切な変更、ネットワークアダプターの修正、AWS KMSを使用したOSのアクティベーションを行う
EBS:AWS仮想サーバの外付けHDD
AWS KMS:暗号化キーを安全に保護し、他の AWS のサービスやカスタムアプリケーションに対して暗号化/復号、署名、および検証の実行を許可するウェブサービス
ネットワーク構築
まずはオンプレ想定(10.0.0.0/16 & 10.0.0.0/24)、ステージング(10.1.0.0/16 & 10.1.0.0/24)、ターゲットVPC(10.2.0.0/16 & 10.2.0.0/24)を作成する。
次にオンプレ想定VPC上にパブリックIPありでユーザデータに以下の通り入力し、HTTPをセキュリティグループに追加して作成する。
#!/bin/bash
yum -y update
yum -y install httpd
systemctl enable httpd.service
systemctl start httpd.service
パブリック IPv4 DNSにHTTPでアクセスすると、Apacheのトップページが表示される。
また、SSH通信できることを確認する。
CloudEndureアカウントの作成
まずは作成ページに移動する。
CloudEndure作成ページ:https://aws.amazon.com/jp/cloudendure-migration/
CloudEndure Migrationの無料ライセンスを取得ボタンを押し、メールアドレスとパスワードを入力する。
メールが届くので、confirm your account requestのリンクを開き、Sign In to the CloudEndureを押し、先ほどのメールアドレスとパスワードを入力し、ログインする。
ポップアップが表示されるため、StartボタンとContinueボタンを押す。
those permissionのリンクを押して、リンク先のJSONを全てコピーする。
IAMの画面に移動し、ユーザタブからユーザの追加を押し、アクセスの種類はプログラムによるアクセスを選択する。
既存のポリシーを直接アタッチを選択し、ポリシーの作成を押す。
JSONに先ほどコピーした内容を入力し、作成する。
作成したポリシーをアタッチし、ユーザを作成し、
.csv のダウンロードを必ず行い、紛失しないようにする。
csvを開き、Access keyとSecret access keyをコピーしてCloudEndureの画面で貼り付け、Saveボタンを押す。
レプリケーション実行
CloudEndureの画面でSetup & Infoを開き、REPLICATION SETTINGSタブを選択する。
Migration SourceにはOther Infrastructure、Migration TargetにはAWS Asia Pacific(Tokyo)を選択し、VPCにはステージング環境のVPCを選択し、保存する。
以下のようなwgetコマンドが表示されるのでコピーする
wget -O ./installer_linux.py https://console.cloudendure.com/installer_linux.py
ソースVPCに作ったEC2に接続し、上記のコマンドを実行する。
次に、CloudEndureのPythonコマンドをコピーして実行する。
ここまでオンプレ想定の環境にCloudEndureエージェントがインストールされる。
この時点ですでにレプリケーションも始まっている。
CloudEndureの画面に戻ると自動で画面が切り替わり、DATA REPLICATION PROGRESSがContinuous Data Replicationになるまで待機する。(15分ほどかかる)ここまで完了すればカットオーバーができる状態となる。
カットオーバー
まず、CloudEndureでレプリケーション完了したリソースを選択し、BLUEPRINTタブを選択する。
MachineTypeを入力し、サブネットはターゲットVPCを選択し、プライベートIPはCreateNewを選択して保存する。
以下のコマンドでオンプレ想定EC2の表示ページを変更する。
sudo sh -c 'echo CloudEndureHandson >> /var/www/html/index.html'
CloudEndureでレプリケーション完了したリソースを選択し、LAUNCH TARGET MACHINEを押し、カットオーバを選択する。
Job Progressを押せば状況が確認できる。
Job finishedが表示されたらOK。(完了まで数分かかる)
EC2を開くと、レプリケーションサーバ(CloudEndureからのレプリケーション先となるサーバ)、コンバータサーバ(各種変換やクラウドツールのインストール)、ターゲットサーバ(IPアドレスが表示されたサーバ)があり、このターゲットサーバにHTTPでアクセスし、HTMLリソースが表示されることを確認する。
12:AWS 環境のコード管理 AWS CloudFormationで Web システムを構築する
なぜ、コードで管理するのか。
構成がコード管理されていないと…
・手作業で行うと時間がかかる、再現性も乏しい、ドキュメントを作るのも時間がかかり記述漏れもある、複製が難しくヒューマンエラーもある。
・アプリケーションはCI/CDにしていても、インフラも自動化しないと、両者の品質に差が出る。
イベントへの対応がコード管理されていないと…
・人為的ミス発生や対応内容の一貫性への懸念
Well-Archtectedフレームワーク
- 運用をコードとして実行する
- ドキュメントに注釈をつける
- 定期的に、小規模な、元に戻すことができる変更を適用する
- 運用手順を定期的に改善する
- 障害を予想する
- 運用上の全ての障害から学ぶ
コードを使った運用のポイント
- コードで全ての構成を定義→同じ環境を迅速に繰り返し作成可能(CI/CDやCloudFormation)
- イベントに対してスクリプトで対処→自動的に同じ処理を繰り返し実施(CloudWatchの定期イベントやイベントドリブン)
- アプリケーションと同じ手法でコードを開発→コードと作成したインフラの品質を担保(CI/CD同様に継続的な品質の担保を行う)
CloudFormation:テキストファイル(テンプレート)を使用して、スタック(AWSリソースの集合)を作成し、AWSリソースを環境構築するサービス。作成、変更、削除をまとめて行うことができる。
作成:テンプレートに定義された構成をスタックで自動作成。並列で行い、依存関係がある場合は自動で解決。
変更:スタックに前回との差分を適用。リソース変更時には無停止変更、再起動、再作成のいずれかが発生。Change Setを作ることで差分の内容を事前に確認可能。
削除:依存関係を解決しつつリソースを全て削除。データストアはスナップショットの保持が可能。
テンプレートはスタックの設計図で、どのリソースをどう起動するか記述されている。
必須なのはResources(EC2などのスタックを構成するリソースの定義)のみ。
基本的にはテンプレートリファレンスを確認して、記述を行う。
テンプレートリファレンス:https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/template-reference.html
環境構築
まずCloud9を構築する。
CloudFormationの画面に移動し、スタックの作成を押し、ハンズオンでダウンロードしたファイル(01_vpc.yml)をアップロードし、作成するとVPCが作成される。
Cloud9を開き、ダウンロードしたcfnフォルダを送る。
なお、Cloud9ではなくEC2で行っている場合は以下のようにフォルダを圧縮した後に送る。
zip -r cfn.zip cfn
scp -i キーペア名 cfn.zip ec2-user@パブリック IPv4 DNS:/home/ec2-user
SSH通信後に以下の通り解答する
unzip cfn.zip
まず、01_vpc.ymlを開いて、PublicSubnet1の名前をPublicSubnet1-updateにする
開き方(操作方法はvimで調べる)
vi 01_vpc.yml
以下のコマンドで実行済みのスタックと手元にある更新後のスタックの差分を確認する
aws cloudformation validate-template --template-body file://01_vpc.yml
以下のコマンドで実行済みスタックを差分更新する
aws cloudformation update-stack --stack-name 実行済みスタック名 --template-body file://01_vpc.yml
これでサブネット名が更新される。
EC2の作成
次にEC2を作成する。なお、最初に作成したスタック名をハンズオンと違うものにした場合はvimでファイルを開いて以下を編集する。
Parameters:
VPCStack:
Type: String
Default: スタック名
変更後、作成コマンドを実行する。
aws cloudformation create-stack --stack-name handson-cfn-ec2 --template-body file://02_ec2.yml
なお、上記のものはサブネットの設定をしていないので、設定を変更する。
最初に作成したスタックのパブリックサブネット1の物理IDをコピーして、02_ec2.ymlに貼り付ける。
また、UserDataにインストールコマンドを入力する(パイプで複数行の入力をOKにする。)
Resources:
EC2WebServer01:
Type: AWS::EC2::Instance
Properties:
ImageId: !Ref EC2AMI
InstanceType: t2.micro
SubnetId: サブネットの物理ID
UserData: !Base64 |
#! /bin/bash
yum update -y
amazon-linux-extras install php7.2 -y
yum -y install mysql httpd php-mbstring php-xml
wget http://ja.wordpress.org/latest-ja.tar.gz -P /tmp/
tar zxvf /tmp/latest-ja.tar.gz -C /tmp
cp -r /tmp/wordpress/* /var/www/html/
touch /var/www/html/.check_alive
chown apache:apache -R /var/www/html
systemctl enable httpd.service
systemctl start httpd.service
これで以下の通り更新処理を実行する。
aws cloudformation update-stack --stack-name handson-cfn-ec2 --template-body file://02_ec2.yml
CloudFormationの画面に移動し、完了後、サブネットが最初に作成したものに紐づいているのが確認できる。
また、アクション>インスタンスの設定>ユーザーデータを編集からユーザーデータが入力されていることが確認できる。
次にセキュリティグループの追加をする。
CloudFormationからVPCの物理IDをコピーして以下の通りymlファイルに追加する。
なお、EC2WebServer01と同じインデントでEC2SGを揃えないとエラーになるため注意
EC2SG:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: sg for web server
VpcId: VPCの物理ID
SecurityGroupIngress:
- IpProtocol: tcp
CidrIp: 10.0.0.0/16
FromPort: 80
ToPort: 80
更新処理を実行するとセキュリティグループがVPCにアタッチされて作成される。
aws cloudformation update-stack --stack-name handson-cfn-ec2 --template-body file://02_ec2.yml
RDS,ELBの作成
RDS,ELBを作成するので以下の通り実行する。
aws cloudformation create-stack --stack-name handson-cfn-rds --template-body file://03_rds.yml
aws cloudformation create-stack --stack-name handson-cfn-elb --template-body file://04_elb.yml
ELBのリソースにアクセスすることでワードプレスが開ける。
13:AWS Code サービス群を活用して、CI/CD のための構成を構築しよう!
今回はAWS CodePipelineを使用して、S3やEC2へCI/CDを行う
S3にはCodeCommitにプッシュしたのを契機にデプロイ。
EC2にはCodeCommitにプッシュしたのを契機にCode Buildがビルドし、CodeDeployがビルド成果物をデプロイする。
AWS CodePipeline:フルマネージドな継続的デリバリーサービス。ソースコードの変更をトリガーにビルドやデプロイの流れを自動的に実行する。サービスの流れの中に、CodeCommit、Code Build、CodeDeployがある。
AWS CodeCommit:フルマネージドなソース管理サービス。スケーラブルでセキュア、Gitツールと連携できる。
AWS CodeBuild:ソースコードをコンパイル、テスト実行し、デプロイ可能なソフトウェアパッケージを作成できるサービス。ビルドサーバを立てる必要がなくなる。
AWS CodeDeploy:様々なリソースに対してデプロイを行う。オートスケール構成に対しても自動でデプロイする。
CodeCommitのデプロイ
S3をパブリックアクセスありで作成する。
S3を開いて、プロパティタブを開いて、静的ウェブサイトホスティングを有効にしてインデックスドキュメントをindex.htmlにする。
アクセス許可タブを開いてバケットポリシーに以下の通り入力
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::バケット名/*"
]
}
]
}
index.htmlをアップロードしてバケットウェブサイトエンドポイントを開くことで表示されることを確認。
CodeCommitの画面に移動してリポジトリを作成を選択し、名前を入力して作成。
次に、Cloud9を作成する。
EC2インスタンスで行う場合は、gitとpipのインストールをする。
sudo yum update
sudo yum install git
sudo easy_install pip
SSH通信で接続した後、AWS CodeCommitの認証ヘルパーを参考に設定する。
CodeCommit認証ヘルパー:https://docs.aws.amazon.com/ja_jp/codecommit/latest/userguide/setting-up-https-unixes.html
以下のコマンドを実行
git config --global credential.helper '!aws codecommit credential-helper $@'
git config --global credential.UseHttpPath true
次にユーザー設定を行う。
git config --global user.name "ユーザー名"
git config --global user.email "メールアドレス"
CodeCommitのインストールを行う
pip install git-remote-codecommit
CodeCommitで作成したリソースを開いて、HTTPS (GRC)にクローンコマンドがあるので、実行する
git clone codecommit::ap-northeast-1://リソース名
ディレクトリに移動する
cd クローンしたディレクトリ名
index.htmlを作り少し編集したものを、プッシュする。
git add -A
git commit -m "init"
git push origin master
CodeCommitの画面に移動すると、index.htmlがアップロードされていることが確認できる。
CodePipelineの利用
CodePipelineの画面に移動して、パイプラインを作成ボタンを押す。
ソースプロバイダは先ほど作成したCodeCommitのリソースを選択する。
ビルドステージはスキップし、作成したS3バケットを選択し、デプロイする前にファイルを抽出するにチェックを入れて作成する。
これでパイプラインが作成するため、S3上のファイルが入れ替わる。
また、再度EC2でファイルを編集してプッシュすると、ファイルが入れ替わり、バケットウェブサイトエンドポイントにアクセスして確認できる。
デプロイ先のEC2の作成
まず、IAMに移動し、一般的なユースケースはEC2を選択し、AmazonS3FullAccessをアタッチしてロールを作成する。(S3にビルド成果物が置かれ、それが配置されるため)
EC2の画面へ移動し、先ほどのIAMをアタッチし、セキュリティグループはHTTPを追加し(本来はIPアドレスを絞る)、作成する。
以下のコマンドを実行し、パッケージの更新とhttpdのインストールおよびhttpdの起動とサーバ立ち上げ時にhttpdを起動するようにする。
sudo yum update
sudo yum install httpd -y
sudo systemctl start httpd.service
sudo systemctl enable httpd.service
これでHTTPアクセスするとApacheのページが表示される。
次にCodeDeployエージェントのインストールを行う。
CodeDeployインストール:https://docs.aws.amazon.com/ja_jp/codedeploy/latest/userguide/codedeploy-agent-operations-install.html
以下の通り実行し、エージェントをインストールする。
sudo yum install ruby
sudo yum install wget
wget https://aws-codedeploy-ap-northeast-1.s3.ap-northeast-1.amazonaws.com/latest/install
chmod +x ./install
sudo ./install auto
以下のコマンドを実行して、runnningと出力されればOK
sudo service codedeploy-agent status
CodeBuildの作成
まず、S3を作成する(パブリックアクセスなし)。
このS3にはビルド成果物を置くことになる。
CodeBuildの画面に移動し、ビルドプロジェクトを作成するを押す。
ソースをAWS CodeCommitの先ほど作成したリポジトリ、ブランチをmasterを選択し、
環境でOSをAmazon Linux2、ランタイムをStandard、イメージとイメージのバージョンは一番下のものを選択し、
アーティファクトをタイプはS3で先ほど作成したバケットを選択してビルドプロジェクトを作成する。
ビルドプロジェクトを開き、ビルド詳細タブを選択し、サービスロールを開き、AWSCodeDeployDeployerAccessをアタッチする。
Cloud9(もしくは開発用のEC2)を開き、srcフォルダを作成して、index.htmlを移動させる。
コマンドの場合以下の通り
mkdir src
mv index.html ./src/index.html
srcと同じディレクトリにbuildspec.ymlを作成し、以下の通り記述する。
CodeBuildのリファレンス:https://docs.aws.amazon.com/ja_jp/codebuild/latest/userguide/build-spec-ref.html
version: 0.2
phases:
build:
commands:
- aws deploy push --application-name コードビルドで作成するアプリケーション(後で入力する) --s3-location s3://ビルド成果物を置くS3名/artifact.zip --source src
artifacts:
files:
- '**/*'
base-directory: src
CodeDeployの作成
IAMに移動し、一般的なユースケースはCodeDeployを選択し、作成する。
CodeDeployの画面に移動して、アプリケーションの作成を選択する。
対象はEC2/オンプレミスを選択して作成する。
作成したら、buildspec.ymlのアプリケーション名を作成したものに変更する。
CodeDeployの画面に戻り、作成したアプリケーションを開いて、デプロイグループタブを選択し、デプロイグループの作成を選択。
先ほど作成したIAMロールを設定、環境設定でデプロイ先のEC2インスタンスの設定、AWS CodeDeploy エージェントのインストールはなし(手動で行ったため)、デプロイ設定はAllAtonce、ロードバランシングを有効にするのチェックを外して作成する。
なお、デプロイ設定は、サーバが複数台並んでいる場合に、一気にデプロイしたいかしたくないかで変更する。
index.htmlと同じディレクトリにappspec.ymlを作成し、以下の通り記述する。
CodeDeploy AppSpec File リファレンス:https://docs.aws.amazon.com/ja_jp/codedeploy/latest/userguide/reference-appspec-file.html
version: 0.0
os: linux
files:
- source: index.html
destination: /var/www/html/
gitプッシュを行い、CodeBuildのビルドプロジェクトを開いてビルドの開始ボタンを実行。
ビルド完了後、CodeDeployのアプリケーションを開いて、作成したアプリケーションにチェックを入れてアプリケーションをデプロイするを実行する。
デプロイグループは先ほど作成した物を選択し、リビジョンの場所はビルド成果物置き場のS3のリビジョンを選択し、デプロイを作成する。
なお、IAMをEC2につけ忘れていた場合、以下の通りエラーが発生した。
The overall deployment failed because too many individual instances failed deployment, too few healthy instances are available for deployment, or some instances in your deployment group are experiencing problems.
デプロイのステータスが100%になり、成功すると、デプロイ先EC2サーバにHTTPアクセスすれば、デプロイしたhtmlが表示される。
CodePipelineの作成
CodePipeLineを構築することで、CodeCommitへのプッシュを検知し、自動でビルドまで行うようになる。
CodePipelineを開いて、パイプラインを作成するを選択する。
ソースステージ、ビルドステージ、デプロイステージに作成したCodeCommit、CodeBuild、CodeDeployを設定し作成する。
パイプライン作成のタイミングでフローが一度実行される。
次にCloud9にログインしてソースを編集し、プッシュする。
デプロイ先EC2にHTTPアクセスして、変更後のHTMLが表示されたらOK。
感想
動画視聴だけでなく、実際に一通り構築することで、エラーにも遭遇して、より理解が深まった。
各サービスのUIはよく変更が行われるため、手順よりも実際に何を設定したか理解することで、いつでも誤りなく環境を構築できると感じた。