AWS, 優総研

ポートフォリオ制作なうなんだが…その1

 

 

 

 

 

最短で完成を目指す。

 

※雑記。現状は参考?にするのはおすすめしません。最後に整理します。

 

内容

本の感想投稿掲示板 + Google Books APIとのマッシュアップ

他書評サービスのコミュニティ機能があまり使われておらず成功していないから、Yomuyoは本好きの間で小さくてもコミュニケーションが生まれるものにしたいな。それがこのサービスの意義。

 

  • 収益という目的性があるよって存在意義
    →Amazon APIの売り上げ条件の為採用を断念
  • おすすめの本というコミュニティ
  • Google Books APIがアプリの外見に華やかさを与えてくれる

※Amazon のAP API利用は売上実績がないとAPI利用でエラーになるので断念。Google Book APIでスタートさせて、Amazonアフィリエイトで実績を十分に作れたら、PA APIに移行するのが良いかな?

 

機能

  • Google Books API連携 + Amazonアソシエイト
  • 検索
  • 書評投稿
  • 会員機能 + 投稿
  • 書評ランキング
  • レビュアランキング
  • レコメンド(余裕があれば実装したい)

シンプルに最短で実装する為に機能を一時的にそぎ落とす。

キャッシュ戦略

  • Google Books APIのキャッシュ
    外部APIに負荷を与え過ぎて利用停止されないように、Google Books APIでの問い合わせ結果はElasticache(Redis)に1週間分をキャッシュする。
    →検索結果が高速化してUXも向上
    // まだGoogle Books APIは良いけれど、Amazon PA APIはシビアなので必須。
  • よくある参照結果もキャッシュ
    トップページなど30秒~1分程度キャッシュします。
    →DBへの負荷軽減と高速化。

 

 

技術要素

AWSのフルマネージドとSaaSでなるべくサーバレス構成にしています。

  • 開発ツール:VS Code + Git 済
  • 開発環境[ 構築|更新|テスト]自動化: Bash Shellスクリプト + docker-compose 済
  • 機密情報隠蔽化:KMS + AWS Systems Manager パラメータグループ 済
  • 自動デプロイ:Docker => GitHub => CodePipeline => CodeBuild => ECR +ECS 済
  • CI + ChatOps:GitHub => CodePipeline => CodeBuild + PHPUnit + [ CloudWatch Events => Lambda+KMS => Slack ] 済
  • フレームワーク:Laravel 済
  • データベースGUI管理ツール:phpMyAdmin on Docker 済
  • 言語:PHP7 済
  • バッチ処理:Lambda, CloudWatch(定期スナップショット) 済
  • RDBMS:RDS(MySQL) 済
  • NoSQL:Elasticache for Redis(セッションサーバ) 済
  • オブジェクトキャッシュ:Elasticache for Redis + Laravel 済
  • フロント:Vue.js + Laravel
  • CDN:Laravel + CloudFront + S3 済
  • ログ分析基盤:Cloudwatch + S3 + Athena, Elasticsearch+kibana 済
  • 日時ロギング:CloudWatch Logs(LogGroup)  => Lambda => S3
  • DNS:Route53 済
  • 証明書自動更新:Route53 + ACM + [ ALB|CloudFront ] 済
  • メール送信管理:SendGrid 済
  • メッセージキュー:Laravel + AWS SQS
  • 監視:Mackerel => [ Slack|Twilio ], CloudWatch Alert => SNS => Lambda => Slack
  • 負荷試験:Jmeter, Apache Bench, Locust
  • セキュリティ:ELB+AWS WAF(Trend Micro Managed Rules for AWS WAF) 済
  • ソーシャルログイン(Laravel Socialite+[Facebook, Twitter]) 済
  • いいねボタン:Ajax + jQuery + Laravel 済
  • マークアップ, グリッド:HTML/CSS, Bootstrap4, Laravel Blade 済
  • ER図 自動作成・更新:SchemaSpy on Docker + Nginx 済

 

 

ローカル or EC2

  • local(開発)
    EC2 + docker-compose
    ローコストで開発&確認

ECS

GitHubのブランチ名でデプロイ先を分ける

  • staging(検証)
    ECS(staging)+EC2
    本番と同じ構成でテストして表示や動作を確認します。
  • production(本番)
    ECS(production)+Fargate

Fargateにするとホスト管理の開放、スケールを気にしなくて良い。

 

Laravel

バージョン:5.8

  • CRUD + Eloquent ORM  済
  • リレーション
    tinker, hasMany, belogsTo, many to many,
  • Eagerローディング
    with()によるN+1対策
  • トランザクション 済
    ロック処理,ロールバック, リトライ
  • ログイン 済
  • Ajax + jQuery いいねボタン 済
  • ランキング機能 済
  • ソーシャルログイン(Facebook, Twitter) 済
  • セッション 済
    relfresh(), old()
  • バリデーション 済
    Request, 
  • アクセス管理 済
  • ストレージ + S3連携 済
  • try catch + ログ出力 済
  • 単体テスト(PHPUnit)
  • ページネーション 済
  • サービスプロバイダ(DI) 済
  • メール送信 済
  • システム管理者用ページ
    Vue.js + RestAPI(Laravel)で作る?
  • ジョブキュー・イベント + AWS SQS
  • Artisan
    auth, request, response, rule, middleware, scope, migrate, seeder, tinker,

 

おすすめ書籍

 

 

 

VS Code

マルチプラットフォームで環境に左右されないIDE

 

拡張プラグイン

 

 

SSHでの接続

ターミナルからコマンドラインで接続しておくこと

 

ssh_config

 

 

 

ショートカット

  • 矩形選択
    [Ctrl]+[Shift]+[Alt]+矢印キー

 

 

Route53と各フルマネージドサービスのエンドポイント

  • エンドポイントはそのままではわけが分からなくなるので、AliasやCNAMEでドメイン名に置き換えると管理しやすい。
  • Alias
    ALB, CloudFront, S3
  • CNAME
    RDS, ElastiCache(Redis)

AliasはDNS問い合わせが1回なので通信パフォーマンスが高いがAlias指定できないものがある。RDSなどはCNAMEしか指定できない(2019年07月時点)

 

環境構築シェルを作成

 

完成図

 

 

ディレクトリ作成

 

 

ローカルのみ有効な環境変数の設定

作業を楽にするために設定

 

適用

確認

これでよく利用するディレクトリの指定が楽になる。

 

 

.env.localの作成

開発用の環境変数です。

 

staging(検証)やproduction(本番)環境変数のデプロイ

  1. AWS SSMのパラメータストアにAWS KMSで暗号化させた値を保存
  2. ECSで値を復号してコンテナに環境変数を上書きすることで反映させます

 

 

1_init_Setup_local.sh

環境構築します。実行後はリブートがかかる。

 

 

2_Create_APP.sh

Laravelをインストールします。

プロジェクト名とバージョンを変更できます。

 

 

3_Docker-Run.sh

DockerでLaravel開発環境を立ち上げます

 

実行権限の付与

 

①環境構築スクリプトを実行

 

②Laravelプロジェクトの作成

 

 

docker-compose.yml

 

 

NginxコンテナDockerfile

 

Nginxメイン設定ファイル

 

 

Nginx バーチャルホスト設定ファイル

 

 

PHP-FPMコンテナDockerfile

 

 

 

php.ini

 

PHP-FPM設定ファイル

 

 

Schemaspyコンテナ

 

 

nginx_for_schemaspyコンテナ作成

 

.gitignore設定

 

 

 

③ Docker起動スクリプト実行

 

④ Docker関連ディレクトリをLaravelプロジェクトに複製する

$HOME/yomuyo-docker-template/src/docker/を削除する。

 

Laravel

http://IPアドレス/

 

phpMyAdmin

http://IPアドレス:8080

  • ユーザ:root
  • パスワード:naishodayo
    ※docker-compose.ymlでmysql56コンテナで設定しているもの

 

 

SchemaSpy

http://IPアドレス:8081

 

 

外部キー制約を行うとリレーションが確認出来ます。

 

 

 

ローカル用 更新スクリプト作成

Laravelの設定ファイル変更などした時はこのスクリプトを叩いて反映させる。

 

update.sh(通常更新用)

 

 

 

hard_update.sh(コンテナイメージを変更した時など)

 

実行権限付与

 

実行

更新されたらOK

 

 

ECSへのデプロイ用ファイル【CodeBuild用builspec.yml】作成

 

 

@see

 

 

 

時刻、タイムゾーン設定

 

 

データベース接続設定変更

Auroraだと読み込み、書き込みで負荷分散でスケールできるように分かれるので指定が必要。

今回はRDSなのでこういう形にもしなくて良いが、後々を考えてこうする。

 

ProductionをHTTPS化する事前準備

{{ asset(‘パス’) }}を利用している場合、本番環境にデプロイするとパスが読み込めなくなる。

これをすることで回避できる。

AWS SSMとECSコンテナの環境変数を利用して、

  • キー:APP_ENV
  • 値:production

となるようにデプロイすることでこの設定が有効になります。

 

duskを無効化する

 

 

Laravelのログを標準エラーに出力する

 

 

 

 

 

Dockerのログ確認

 

まずコンテナのIDを確認します。

 

リアルタイムでログを確認する

サイトにアクセスするたびに標準出力がログとして出ているか確認できる。

 

ファイル更新した場合のローカルでの確認

これで更新される。

 

 

Laravel Whoops!での環境変数を隠す

 

これをやらないと「ひえっ」となる。

 

スタックトレースを見せない

  1. .envでAPP_DEBUG=falseを設定
  2. 「php artisan config:clear」を実行

本番でのデプロイでは必ず自動実行されるようにすること。

 

 

AWS Systems Manager  パラーメタストアによる機密情報隠蔽化

 

.envに記載する内容をパラメータストアに格納します。パラメータはECSで参照されてコンテナの環境変数に渡します。

 

例えばこんな感じ

  • 名前
    /yomuyo/prod/ecs/database_master_host
  • 利用枠
    標準
  • KMS の主要なソース
    現在のアカウント
  • タイプ
    安全な文字列
  • KMS キー ID
    alias/aws/ssm

  • db-master.yomuyo.net

 

設定出来ました、パラメータグループの名前は階層化できるので階層化したほうがわかりやすいです。

ここからはCUIでどんどんパラメータを追加していきます。

 

AWS CLIでパラメータストアに登録

 

AWS CLIのインストール

 

IAMのプログラムアクセスユーザでIDとキーを取得して設定

 

パラメータストアに適用

 

 

AWS S3とLaravelの連携

 

変数の設定

S3 バケットはWEB公開する予定なので、バケット名はサブドメイン『s3.yomuyo.net』にします。

 

1. AWS S3 バケットの作成

バケットの作成

 

WEB公開設定を許可します。

 

/yomuyo-img/*以下にWEBでの公開許可を与えます。

 

設定の適用を実施します。

 

※設定の確認

 

GUIで確認

 

s3.yomuyo.netバケットを確認出来ました。

公開設定もされていますね。

 

フォルダの作成

  • books
    本のサムネイル
  • profile
    ユーザプロフィールの画像

 

ACM バージニア

後で設定するCloudFront用の証明書に、ACM バージニアリージョンで証明書を作成する必要があります。

 

 

もちろんDNS検証。ウィザードに沿ってRoute53での認証リクエストを進めます。

 

 

発行されました。

 

CloudFront

 

 

 

 

 

 

 

 

 

『s3.yomuyo.net』にCloudFrontを紐づける。

 

ちゃんとCloudFrontから配信されていることがわかります。

 

 

2. AWS S3のyomuyo-imgバケットを操作可能なIAMユーザの作成

 

ポリシー設定用jsonファイルの作成

 

ポリシーの作成

“Arn”: “arn:aws:iam::xxxxxx:policy/S3-Read-Write-Policy”をメモしておきます

 

 

IAMユーザの作成

 

ユーザにポリシーを紐づけます

 

アクセス用の認証情報の作成

ユーザのシークレットキーとアクセスIDを控える

 

3. Laravel 設定

 

flysystem-aws-s3-v3のインストール

 

.envの設定

先ほど得た認証情報を記入します。

 

4. Laravel から S3への投稿

 

/app/Http/Controllers/HomeController.php

 

 

/app/Models/Review.php

  • users←reviews→books

reviewsテーブルは中間テーブルになっている。

usersとbooksは多対多の関係なので、reviewsテーブルが必要。

 

 

画像アップロードの確認

 

 

 

 

 

ECS実行用ロールの作成 「ecsTaskExecutionRole」

 

ポリシーの付与を行う

  • AWS管理ポリシー
    AmazonECSTaskExecutionRolePolicy
  • インラインポリシー
    SSM-Value-Get-Policy

 

SSM-Value-Get-Policy

 

 

 

ECR

 

 

 

 

 

 

ECRにログイン

 

イメージの確認

 

ECRにイメージにタグ付け

URI:タグという形で設定できます。

 

ECRにPushします。

 

こんな風にイメージがECRに格納されます。

 

 

ECS

 

タスク定義

  • タスク定義名:yomuyo

 

 

 

EC2を選択して【次のステップ】

 

 

タスクロールをきちんと指定します。AWS System managerのパラメータグループから値を受け取るのに必要です。

 

 

コンテナの追加

 

 

PHP-FPMコンテナ

  • コンテナ名:php-fpm
  • イメージ:xxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/yomuyo/php-fpm:latest
  • メモリ制限:ハード制限 300(MB)
  • 作業ディレクトリ:/app

※イメージを指定すること

 

 

ログの設定を行います。

 

 

ここでパラメータストアで設定した値が生きてきます。

 

Nginxコンテナ

  • コンテナ名:nginx
  • イメージ:xxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/yomuyo/nginx:latest
  • メモリ制限:ハード制限 300(MB)
  • ポートマッピング(TCP):0 , 80
  • リンク:php-fpm

 

ホストポートは「0」、コンテナは80にします。

80, 80にするとデプロイで失敗します。

 

ログの設定を行います。

 

 

 

 

 

 

 

【作成】をクリックします。

 

 

 

 

 

 

クラスタの作成

 

 

 

  • メモリなどのスペック不足でECSでうまく動かなかったりする、EC2インスタンスタイプは【t2.small】以上のインスタンスを選ぶようにする。
  • キーペアの指定
    ステージングと本番はFargateでログインをしないが,
    開発はEC2でSSHによる状態確認をしやすいようにしたほうが開発しやすい。

 

 

 

 

ALB

 

 

 

ECSのインスタンスが利用しているVPCを選択する。

 

 

 

ターゲットに登録して、【次の手順】へ。

 

【作成】で完了

 

 

 

ALBからデプロイ時間の調整(重要)

【ターゲットグループ】から【属性の編集】をクリックします。

 

「300」秒から「30」秒へ変更しました。

これでECSへのデプロイ完了が速くなります。

 

サービスの登録

 

 

 

 

 

新規作成のところを選択して、

 

こうする。

 

 

 

 

 

 

 

 

 

ALBとECSとの連携での重要な設定

ECSのEC2インスタンスのセキュリティグループのインバウンドにALBのSGを全許可受け入れを行う。こうすることでECSが行うコンテナへの動的ポートマッピングに対応しできる。公式にも書いてある。

ユーザの80番アクセスがALBに渡り、ALBからクラスタ化されたコンテナに伝わる。

 

ALB経由でアクセスを確認

http://yomuyo-alb-xxxxxxxx.ap-northeast-1.elb.amazonaws.com/

 

GitHub

GitHub上で「yomuyo.git」リポジトリを作る

 

GitHubにアップロードできるようにする

 

 

 

リポジトリにpushする

pushできたらおーけ。

 

個人設定

 

 

developブランチ

developブランチの作成

 

developブランチに移動する

 

現在のブランチの確認

 

developブランチにpushする

 

 

 

 

CodePipeline

【パイプラインを作成する】をクリックします。

 

※なんでCircleCIじゃないの?GitHub + CodePipeline + CodeBuild + ECR + ECSの理由

  • CircleCIは複数Dockerfileでの設定は辛い。
    ただし1つだけのDockerfileであればCircleCI Orbsを利用すると簡単。
  • AWS CodePipelineを利用すればセキュリティが向上する
    認証キーなどの環境変数をCircleCI上に保存するよりセキュア。

そういうわけで今回はCodePipelineで構築、お客様の要望によってCircleCIは触らざるを得ないという辛みがある。

 

 

 

 

 

 

CodeBuild

 

  • AmazonEC2ContainerRegistryFullAccess
  • AmazonEC2ContainerServiceFullAccess

 

  • AWS_ACCOUNT_ID
    9xxxxxx7
  • AWS_DEFAULT_REGION
    ap-northeast-1
  • PROJECT_NAMESPACE
    yomuyo

 

 

これでCodeBuildはおしまい。

 

CodePipelineに戻る

 

 

 

Deployまで成功すればOK

 

※エラー対応

[Container] 2019/06/14 16:22:45 Phase context status code: COMMAND_EXECUTION_ERROR Message: Error while executing command: $(aws ecr get-login –no-include-email –region ap-northeast-1. Reason: exit status 2

ロールにポリシーが付与されていないことが原因

ロールを確認して、IAMからポリシーを付与する。

ここのロールに後でポリシーをつけよう。

 

  • AmazonEC2ContainerRegistryFullAccess
  • AmazonEC2ContainerServiceFullAccess

ポリシーを付与する

 

CodePipelineから確認して、ECSへのデプロイまで完了したか確認出来たら完了。

 

自動デプロイ環境が出来たので、アプリ開発に集中しましょう~!

 

ポートフォリオ制作なうなんだが…その2

 

 

 

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)