想ひ出のへっぽこBlogⅡ from35

~ 自身の備忘録および学習促進のためにブログります。~

想ひ出29: AWS/Elastic Beanstalkに入門する/2

f:id:moqrin3:20190129001508p:plain

おはようございます、moqrinです。

前回の続きです。

今回のテーマはこちらです。

ElasticBeanstalkでLaravelアプリケーションをRDSと接続して設定する

以下、コンソールベースでゴシゴシ作成するパターンと、コマンドで叩いて作成するパターンで進めます。(途中、ズルしてコンソールも使います。。)

目次

1. ElasticBeanstalkでLaravelアプリケーションをRDSと接続して設定する(コンソールベース)

2. ElasticBeanstalkでLaravelアプリケーションをRDSと接続して設定する(EB CLIベース)

3. 宿題

4. オマケ: EB CLIのインストール


1. ElasticBeanstalkでLaravelアプリケーションをRDSと接続して設定する(コンソールベース)

それでは進めていきます。なお、RDSにMySQLのDBがあることが前提です。

① アプリケーションの作成

f:id:moqrin3:20190129002216p:plain

f:id:moqrin3:20190129002248p:plain

PHPで環境を作成

f:id:moqrin3:20190129002313p:plain

③ カスタム設定

f:id:moqrin3:20190129003337p:plain

ネットワークをカスタムVPCにします。

f:id:moqrin3:20190129003943p:plain

色々便利なので、キーペアを設定しておきましょう。

f:id:moqrin3:20190129003323p:plain

環境変数の追加やドキュメントルートを設定しておきましょう。

f:id:moqrin3:20190129003625p:plain

f:id:moqrin3:20190129003924p:plain

そしたら作成します。

f:id:moqrin3:20190129004052p:plain

思いっきりエラー出てますが、無視していいです。

④ セキュリティグループの編集

RDSへ接続するセキュリティグループ(以下SG)にEBのSGを追加します。

f:id:moqrin3:20190129003911p:plain

⑤ プロジェクト以下、public/index.phpに接続の情報を追記する

DB接続がちゃんと出来ているか確認します。

f:id:moqrin3:20190129004112p:plain

⑥vender以外の内容をzipにしてアップロードする

※ なお、ディレクトリをそのままzipするとパスがおかしくなっちゃうので注意。

f:id:moqrin3:20190129004740p:plain

f:id:moqrin3:20190129004209p:plain

OKね.

2. ElasticBeanstalkでLaravelアプリケーションをRDSと接続して設定する(EB CLIベース)

次は、.ebextensionsを利用してみたいため、Migrationできるようなアプリケーションで実践します。

こちらを素材として対応させて頂きます。

なお、RDSでMySQLが起動していること、EB CLIをインストールしていることが前提です。

環境変数やドキュメントルート設定のファイルを作成

ソースルートで.ebextensionsディレクトリと設定ファイルを作成しましょう。

mkdir .ebextensions && touch {environmentvariables,php-settings}.config

ファイルを編集しましょう。

# vim .ebextensions/environmentvariables.config

option_settings:
  - option_name: DB_USERNAME
    value: YourDBUserName
  - option_name: DB_PASSWORD
    value: YourDBPassword
  - option_name: DB_HOST
    value: YourDBEndPointURL
  - option_name: DB_DATABASE
    value: YourDBName
# vim .ebextensions/php-settings.config

option_settings:
  aws:elasticbeanstalk:container:php:phpini:
    document_root: /public

Migrationコマンドを叩くmigration.configファイルを作成しましょう。

# vim .ebextensions/migration.config

container_commands:
  key generate:
    command: "php artisan key:generate"
  migration:
    command: "php artisan migrate"

そのままプロジェクトディレクトリでPHP7.2のプラットフォームでEBアプリケーションを作成しましょう。

eb init LaravelApps -p php-7.2  --region ap-northeast-1 --keyname YOUR_KEY_NAME

カスタムVPC内にシングル構成、publicIPを持ったt2.microインスタンスで環境を作成します。

eb create PassportApp --vpc.id YOUR_VPC_ID --vpc.publicip --vpc.ec2subnets YOUR_PUBLIC_SUBNET_ID -i t2.micro --vpc.dbsubnets YOUR_DB_SUBNET_ID --single

環境が作成されたら、RDSへの接続を許可するSGに、作成されたインスタンスに付与されたSGを追加します。(環境がエラーだって怒ってますが無視します。)

f:id:moqrin3:20190129005030p:plain

f:id:moqrin3:20190129005112p:plain

(eb deployでもいいのだけども)とりあえず、Vender以外のソースをzipにしてアップロードします。

はい、成功

f:id:moqrin3:20190129005008p:plain

じゃ見に行きましょう。ちなみに、飛び先は404なので、/passportsを飛び先につけます。

/passports/createで新規作成です。作成します。

f:id:moqrin3:20190129005152p:plain

f:id:moqrin3:20190129005209p:plain

はい、ちゃんとDB接続もうまく動いているっぽいですね。

何かあったらこの辺を確認します。

tail -f /var/log/eb-activity.log

クリーンアップする際は、RDSへのSGからEBのSGを削除してから環境を削除 -> アプリケーション削除。

eb terminate

3. 宿題

色々と雑。。

CodeCommitとの連携とかやってみる。

Flaskアプリケーションでの対応が何かうまくいかなかったので再度トライするー。

4. オマケ: EB CLIのインストール

brewでのインストールがうまくいかず。。。

brew update
brew install awsebcli 

pipで対応してもエラー出まくりで、何だヨこれは・・・と困惑していた。。 これでうまくいった。以前のバージョンが邪魔してたっぽい。

pip uninstall awsebcli
pip3 uninstall awsebcli
pip3 install awsebcli

How to fix eb command not found – Mac Users

http://www.derricksherrill.com/aws/eb-command-not-found/


参考:

Elastic Beanstalk への Laravel アプリケーションのデプロイ

設定ファイル (.ebextensions) による高度な環境のカスタマイズ

Laravel 5.6 CRUD tutorial with example

CodeCommit のGitリポジトリにIAM Roleで接続する

aws:elasticbeanstalk:container:php:phpini 名前空間

想ひ出28: AWS/Elastic Beanstalkに入門する/1

f:id:moqrin3:20190129001508p:plain

おはようございます、moqrinです。

引き続き、今更感満載でElastic Beanstalkに入門(復習?)したので、個人的まとめ1です。

内容としては、公式リファレンス抜粋です。

目次

1. Elastic Beanstalkとは

2. 構成要素

3. デプロイ方式

4. 環境設定のカスタマイズ

5. モニタリングの方法



1. Elastic Beanstalkとは

定番構成の構築・アプリデプロイの自動化サービス

Java, PHP, Ruby, Python, Node.js, .NET, Docker, Goに対応

定番構成

  • ウェブサーバー環境
  • ワーカー環境

2. 構成要素

構成要素 機能
アプリケーション Elastic Beanstalkトップレベルの管理単位
バージョン デプロイ可能なアプリケーション
環境 各環境(ウェブサーバ、ワーカー) に応じて構築されるインフラ環境
環境設定 インスタンスタイプやAutoScalingなどの環境に関連するパラメータ設定

3. デプロイ方式

f:id:moqrin3:20190129001607p:plain

出典: AWS Elastic Beanstalk 環境へのアプリケーションのデプロイ

https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/using-features.deploy-existing-version.html

4. 環境設定のカスタマイズ

  • 環境作成時に直接設定(EB CLI or マネジメントコンソール)
  • 保存済み設定(起動中の環境や過去保存した環境設定を再利用できる)
  • .ebextensions

.ebextensionsとは

  • 環境に対する様々な操作を柔軟に自動化 & 集約可能
  • ソースルートで .ebextensions フォルダに設定ファイルを追加する

5. モニタリング

  • EB CLIでモニタリング(eb health -r)
  • EB マネージメントコンソール
  • CloudWatch Logsを使ってログ監視: CloudWatch Logsへの書き込み権限はIAM Role

では次回、Laravelで実践しましょう。

参考:

WS Black Belt / AWS Elastic Beanstalk

AWS Elastic Beanstalk とは?

想ひ出27: AWS/CodePipelineに入門する/2

f:id:moqrin3:20190128091739j:plain

おはようございます、moqrinです。

前回の続きです。

当記事はCodeDeployを設定してCodePipelineを実行して確認まで、となります。

全部で4ステップで、当記事は3ステップから行います。

  1. Codecommitリポジトリ作成とHttps接続

  2. EC2インスタンスにクローンして確認

  3. CodeDeployの設定 --- ここから

  4. CodePipelineを作成して確認

目次

1. インスタンスに必要なIAMロールを設定

2. appspec.ymlを作成する

3. AWS CodeDeploy でアプリケーションを作成する

4. CodePipelineを作成する

5. CodeCommit リポジトリにPushしてみる

6. 宿題


1. インスタンスに必要なIAMロールを設定

  1. S3からCodeDeployエージェントをインストールするために新しい IAM ロールを作成
# ポリシー
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "s3:Get*",
        "s3:List*"
      ],
      "Effect": "Allow",
      "Resource": "*"
    }
  ]
}

元々のAWSCodeCommitFullAccessと上記を併せて、"CodePipelineForEC2Role"(名前は何でもいいけど)を作成。 こちらをインスタンスに付与します。

f:id:moqrin3:20190128094832p:plain

  1. CodeDeployエージェントをインストール

叩くもよし。起動時に実行させるもよし。

#!/bin/bash
yum -y update
yum install -y ruby
yum install -y aws-cli
cd /home/ec2-user
aws s3 cp s3://aws-codedeploy-ap-northeast-1/latest/install . --region ap-northeast-1
chmod +x ./install
./install auto

f:id:moqrin3:20190128094915p:plain

# エージェントを確認
service codedeploy-agent status

f:id:moqrin3:20190128101305p:plain

インスタンスは準備OK.

appspec.ymlを作成します。

2. appspec.yamlを作成する

appspec.yamlでやりたいこと

う〜ん、、、死ぬほど雑。

ローカルのリポジトリディレクトリを1つ作って、シェルスクリプトを放り込みます。 ちなみに、雑すぎてログで怒られます、、、

mkdir deploy_hooks

# vim deploy_hooks/install_dependencies.sh
#!/bin/sh

cd /var/www/html/YourSampleRepo
virtualenv --python python3 env
source ../env/bin/activate

pip install flask uwsgi flask-sqlalchemy mysqlclient flask-login flask-migrate

mkdir instance
echo "SECRET_KEY = 'secret'
SQLALCHEMY_DATABASE_URI = 'mysql://USER_NAME:USER_PASS@ENDPOINT_URL'
SQLALCHEMY_TRACK_MODIFICATIONS = True" >>instance/config.py

echo "from run import app

if __name__ == \"__main__\":
    app.run()" >wsgi.py

echo "[uwsgi]
module = wsgi:app

master = true
processes = 5

socket = flaskr.sock
chmod-socket = 660
vacuum = true

die-on-term = true" >flaskr.ini

flask db init
flask db migrate
flask db upgrade

systemctl start flaskr && systemctl start nginx
# vim deploy_hooks/stop_delete.sh

#!/bin/sh

systemctl stop flaskr && systemctl stop nginx

rm -rf /var/www/html/YourSampleRepo

mysql -h ENDPOINT_URL -u USER_NAME -pUSER_PASS DB_NAME -N -e 'show tables' | while read table; do mysql -h ENDPOINT_URL -u USER_NAME -pUSER_PASS -e "drop table $table" DB_NAME; done

そしたら、appspec.ymlをディレクトリ直下に格納しておきます。

# appspec.yml

version: 0.0
os: linux
files:
  - source: /
    destination: /var/www/html/YourSampleRepo
hooks:
   BeforeInstall:
     - location: deploy_hooks/stop_delete.sh
   AfterInstall:
     - location: deploy_hooks/install_dependencies.sh

3. AWS CodeDeploy でアプリケーションを作成する

① アプリケーションを作成

f:id:moqrin3:20190128095025p:plain

② デプロイグループの作成

f:id:moqrin3:20190128095237p:plain

f:id:moqrin3:20190128095324p:plain

ま、適当に。

4. CodePipelineを作成する

f:id:moqrin3:20190128095505p:plain

ソースはCodeCommit

f:id:moqrin3:20190128095602p:plain

今回ビルドはしないので、スキップ

そしてデプロイ

f:id:moqrin3:20190128095703p:plain

5. CodeCommit リポジトリにPushしてみる

早速Pushして確認。

ついでに、タイトルとか変えてみる。

f:id:moqrin3:20190128100405p:plain

CodePipeline上でも確認

f:id:moqrin3:20190128095934p:plain

表示

f:id:moqrin3:20190128100056p:plain

OK.

何かエラーが有った場合はこの辺を見よう。

tail -f /var/log/aws/codedeploy-agent/xxxx.log
tail -f /opt/codedeploy-agent/deployment-root/deployment-logs/xxxx.log

6. 宿題

かなり雑なやり方だったので、もうちょっと整備した方が宜しいですね。。。

参考:

チュートリアル: シンプルなパイプラインを作成する (AWS CodeCommit リポジトリの場合)

AWS BlackBelt/AWS CodeDeploy

AWS CodeDeploy のサービスロールを作成する

CodeCommit のGitリポジトリにIAM Roleで接続する

AppSpec fileを追加する

AWSのCodeDeployでエラーになったらAgentを試そう!

想ひ出26: AWS/CodePipelineに入門する/1

f:id:moqrin3:20190128091739j:plain

おはようございます、moqrinです。

いつもの如く、今更感満載ですがCodePipelineに入門したので、そのまとめ1です。

当記事はCodeCommitリポジトリを作成して、EC2インスタンスにクローンして確認まで、となります。

次回がCodeDeployを利用したCodePipelineの体験となります。

素材としては、Flaskのチュートリアルブログを使います。

全部で4ステップで、当記事は2ステップまでを行います。

  1. Codecommitリポジトリ作成とHttps接続

  2. EC2インスタンスにクローンして確認 --- ここまで

  3. CodeDeployの設定

  4. CodePipelineを作成して確認

目次

1. CodeCommitリポジトリ作成してHttpsで接続/ローカル

2. Httpsで接続してGitクローン/インスタンス

3. 表示までを確認

4. 宿題


1. CodeCommitリポジトリ作成してHttpsで接続/ローカル

前提

  • AWS CodeCommit にアクセスする権限を持っている

  • AWS CLI,Git をインストールおよび設定済み


① CodeCommitでリポジトリを作成

早速作成します。

f:id:moqrin3:20190128092246p:plain

② CodeCommit への HTTPS 接続用の Git 認証情報を作成

SSH接続でも出来ますが、インスタンスからの接続に合わせてHttps接続にしておきます。

下記コマンドを叩くだけです。

git config --global credential.helper '!aws codecommit credential-helper $@'
git config --global credential.UseHttpPath true

こんなんが追記されるはずです。

[credential]    
    helper = !aws --profile CodeCommitProfile codecommit credential-helper $@
    UseHttpPath = true

そしたら確認します。

git config --global --edit

問題なさそうなら、適当な場所にリポジトリをクローンしちゃいます。

f:id:moqrin3:20190128092506p:plain

③ ローカルからファイルを追加する

  • ローカルリポジトリにファイルを追加します。

  • .gitignoreを作成します。

  • ローカルリポジトリからGit Add & Commit & Push

ちなみに、「macOS を使用している場合は、HTTPS を使用して AWS CodeCommit リポジトリに初めて接続すると、約 15 分後に後続のアクセスが失敗します。」とか書いているので、いきなりエラーが発生した場合にご留意下さい。いきなりエラーが出たとき、ワタクシはキョドりました・・・

次はサーバーでの対応に進みます。

2. Httpsで接続してGitクローン/インスタンス

① AWSCodeCommitFullAccessを付与してインスタンスサーバーを起動する

f:id:moqrin3:20190128092602p:plain

② Git インストール

yum install -y git

③ 先ほどの認証情報ヘルパーを同様に設定して確認

git config --global credential.helper '!aws codecommit credential-helper $@'
git config --global credential.UseHttpPath true

これで、無事Git クローンできるはずです。

ここから先は、以前対応した手順とほぼ同様です。 想ひ出17: GCP/Flask1.0/Nginx/GCEにデプロイする

なので、地道な手作業の手順だけ記しておきます。

3. EC2インスタンスにクローンして確認

Amazon Linux 2 AMI (HVM), SSD Volume Type, Python3.6, Flask1.0, RDS(MySQL5.7)で対応。

# epel-releaseをインストール
amazon-linux-extras install -y epel
# amazon-repoのpriorityを変更
vim /etc/yum.repos.d/amzn2-core.repo
-> %s/priority=10/priority=99

vim /etc/yum.repos.d/amzn2-extras.repo
-> %s/priority = 10/priority = 99
# mariadbの削除
yum -y remove mariadb-libs
rm -rf /var/lib/mysql/
# MySQL5.7公式 yumリポジトリの追加
yum -y localinstall http://dev.mysql.com/get/mysql57-community-release-el7-7.noarch.rpm
# インストール
yum -y install mysql-community-server mysql-community-devel
# Nginxとその他インストール
yum install -y nginx gcc wget
# Python 3.6 をインストール
yum install -y https://centos7.iuscommunity.org/ius-release.rpm
yum install -y python36u python36u-libs python36u-devel python36u-pip
# エイリアスの設定
ln -s /bin/python3.6 /bin/python3
# pipのインストール
mkdir -p /var/www/html; cd /var/www/html
wget https://bootstrap.pypa.io/get-pip.py
python get-pip.py
# virtualenv のインストール
pip install --upgrade virtualenv
virtualenv --python python3 env
# CodeCommit レポジトリからgit cloneする
git clone https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/YourSampleRepo
# virtualenv切り替え
cd YourSampleRepo
source env/bin/activate

# ライブラリのインストール
pip install flask uwsgi flask-sqlalchemy mysqlclient flask-login flask-migrate

# DB接続設定
mkdir instance
echo "SECRET_KEY = 'secret'
SQLALCHEMY_DATABASE_URI = 'mysql://USE_NAME:USER_PASS@ENDPOINT_URL/DB_NAME'
SQLALCHEMY_TRACK_MODIFICATIONS = True" >instance/config.py

# Create the WSGI Entry Point
echo "from run import app

if __name__ == \"__main__\":
    app.run()" >wsgi.py

# Creating a uWSGI Configuration File
echo "[uwsgi]
module = wsgi:app

master = true
processes = 5

socket = flaskr.sock
chmod-socket = 660
vacuum = true

die-on-term = true" >flaskr.ini

# 起動
uwsgi --socket 0.0.0.0:8000 --protocol=http -w wsgi:app &

# Create a Systemd Unit File
echo "[Unit]
Description=uWSGI instance to serve myproject
After=network.target

[Service]
User=プロジェクトディレクトリのユーザー
Group=nginx
WorkingDirectory=/var/www/html/YourSampleRepo
Environment="PATH=/var/www/html/env/bin"
ExecStart=/var/www/html/env/bin/uwsgi --ini flaskr.ini

[Install]
WantedBy=multi-user.target" >/etc/systemd/system/flaskr.service

# uwsgi起動
systemctl daemon-reload
systemctl start flaskr;systemctl enable flaskr

# Configuring Nginx to Proxy Requests
echo "    server {
        listen       80;
        server_name  moqrin3.flask.com;
        
        location / {
          include uwsgi_params;
          uwsgi_pass unix:/var/www/html/flaskr-tutorial/flaskr.sock;
        }
     }" >/etc/nginx/conf.d/moqrin.conf

# 起動
systemctl start nginx; systemctl enable nginx

# # Migration
cd /var/www/html/YourSampleRepo
flask db init
flask db migrate
flask db upgrade
# 何かうまくいかない場合の確認は
systemctl status flaskr -l
vim /etc/hosts
xxx.xxx.xxx.xxx moqrin3.flask.com

表示確認

f:id:moqrin3:20190128092741p:plain

4. 宿題

あれ、AutoScalingとCodeDeploy,CodePipelineってどういう感じになるか確認しなきゃ。

参考:

AWS CLI 認証情報ヘルパーを使用して Linux, macOS, or Unix 上で AWS CodeCommit リポジトリへの HTTPS 接続のセットアップステップ

mysql_confがない場合(mysql-community-serverを使っていて)

# 想ひ出25: AWS/OpsWorksに入門する/1

f:id:moqrin3:20190126231935j:plain

おはようございます、moqrinです。

今回も今更感満載ですが、OpsWorksをやってみました。

これもしばらく触らないと忘れるため、個人的後日振り返り用でございます。

OpsWorksはあまり人気がないのか皆さまの記事がない印象でした。

5年近く前のハンズオンとかやってみたんですが、何かうまく出来なかったこと、

Chefともあまり馴染みがないので、、CloudFormationで下準備して、

以前のバージョンChef11のチュートリアルを体験しました。

また後日、Chef12で進めるつもりでございます。

目次

1. AWS OpsWorksとは

2. CloudFormationで準備

3. Chef11のチュートリアルを体験

4. 宿題


1. AWS OpsWorksとは

AWS OpsWorksとは(現在)以下の3つ。

  • OpsWorks for Puppet Enterprise
  • OpsWorks for Chef Automate
  • OpsWorks スタック --- 今回触るやつ

OpsWorksスタックとは

下記表で構成される。

構成要素 機能
スタック 最上位の管理リソース
レイヤー LB,DB,ApplicationServerなどの階層を指す
インスタンス アプリケーションを提供するためのEC2インスタンスなどのリソース
アプリケーション(Apps) アプリケーションサーバーにデプロイするアプリケーション

どんなか?

ElasticBeanstalkよりも柔軟にアプリケーションに対応できる

スタック、レイヤー単位でモデリング・コード構成管理が可能

サーバーの起動やアプリケーションのデプロイなどのライフサイクルイベントに自動でレシピ実行ができる

インスタンス内部にOpsWorks エージェントが動作しているため、任意のタイミングでインスタンスへ、リモートコマンド(AWSマネージメントコンソール、AWS SDKAWS CLI)を実⾏可能

2. CloudFormationで準備

OpsWorksではClassic Load Balancer しか対応していないようなのでClassic Load BalancerおよびVPCなどをCloudFormationで適当に作成。
(※ 色々と望ましくない設定です。)

インスタンスはOpsWorksのスタック上のインスタンスで起動させるため、用意しません。

# Opsworks11_sample.json
{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Parameters" : {
    "KeyName": {
      "Description" : "Name of an existing EC2 KeyPair to enable SSH access to the instances",
      "Type": "String",
      "MinLength": "1",
      "MaxLength": "255",
      "AllowedPattern" : "[\\x20-\\x7E]*",
      "ConstraintDescription" : "can contain only ASCII characters."
    },
    "SSHLocation": {
      "Description": " The IP address range that can be used to SSH to the EC2 instances",
      "Type": "String",
      "MinLength": "9",
      "MaxLength": "18",
      "Default": "0.0.0.0/0",
      "AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})",
      "ConstraintDescription": "must be a valid IP CIDR range of the form x.x.x.x/x."
    }
  },

  "Mappings" : {
    "AWSInstanceType2Arch" : {
      "t2.micro"    : { "Arch" : "HVM64"  }
    },

    "AWSRegionArch2AMI" : {
      "ap-northeast-1"   : {"HVM64" : "ami-00a5245b4816c38e6", "HVMG2" : "ami-053cdd503598e4a9d"}
    }

  },

  "Resources": {
    "VPC": {
      "Type": "AWS::EC2::VPC",
      "Properties": {
        "CidrBlock": "10.0.0.0/16",
        "EnableDnsHostnames": "true",
        "Tags": [
          {
            "Key": "Name",
            "Value": "OpsWorksVPC"
          }
        ]
      }
    },
    "PublicSubnet1" : {
      "Type" : "AWS::EC2::Subnet",
      "Properties" : {
        "VpcId" : { "Ref" : "VPC" },
        "CidrBlock" : "10.0.0.0/24",
        "AvailabilityZone" : { "Fn::Select" : [ "0", { "Fn::GetAZs" : { "Ref" : "AWS::Region" } }]},
        "Tags" : [ {"Key" : "Name", "Value" : "PublicSubnet1" } ]
      }
    },
    "PublicSubnet2" : {
      "Type" : "AWS::EC2::Subnet",
      "Properties" : {
        "VpcId" : { "Ref" : "VPC" },
        "CidrBlock" : "10.0.1.0/24",
        "AvailabilityZone" : { "Fn::Select" : [ "1", { "Fn::GetAZs" : { "Ref" : "AWS::Region" } }]},
        "Tags" : [ {"Key" : "Name", "Value" : "PublicSubnet2"} ]
      }
    },
    "PrivateSubnet1" : {
      "Type" : "AWS::EC2::Subnet",
      "Properties" : {
        "VpcId" : { "Ref" : "VPC" },
        "CidrBlock" : "10.0.2.0/24",
        "AvailabilityZone" : { "Fn::Select" : [ "0", { "Fn::GetAZs" : { "Ref" : "AWS::Region" } }]},
        "Tags" : [ {"Key" : "Name", "Value" : "PrivateSubnet1"} ]
      }
    },

    "PrivateSubnet2" : {
      "Type" : "AWS::EC2::Subnet",
      "Properties" : {
        "VpcId" : { "Ref" : "VPC" },
        "CidrBlock" : "10.0.3.0/24",
        "AvailabilityZone" : { "Fn::Select" : [ "1", { "Fn::GetAZs" : { "Ref" : "AWS::Region" } }]},
        "Tags" : [ {"Key" : "Name", "Value" : "PrivateSubnet2"} ]
      }
    },

    "InternetGateway": {
      "Type": "AWS::EC2::InternetGateway",
      "Properties": {
        "Tags": [
          {
            "Key": "Name",
            "Value": "OpsWorksIGW"
          }
        ]
      }
    },
    "DHCPOptions": {
      "Type": "AWS::EC2::DHCPOptions",
      "Properties": {
        "DomainName": "ap-northeast-1.compute.internal",
        "DomainNameServers": [
          "AmazonProvidedDNS"
        ]
      }
    },
    "NetworkAcl": {
      "Type": "AWS::EC2::NetworkAcl",
      "Properties": {
        "VpcId": {
          "Ref": "VPC"
        }
      }
    },
    "PublicRouteTable": {
      "Type": "AWS::EC2::RouteTable",
      "Properties": {
        "VpcId": {
          "Ref": "VPC"
        },
        "Tags": [
          {
            "Key": "Name",
            "Value": "public"
          }
        ]
      }
    },

    "AttachGateway": {
      "Type": "AWS::EC2::VPCGatewayAttachment",
      "Properties": {
        "VpcId": {
          "Ref": "VPC"
        },
        "InternetGatewayId": {
          "Ref": "InternetGateway"
        }
      }
    },

    "PublicRoute" : {
      "Type" : "AWS::EC2::Route",
      "DependsOn" : "AttachGateway",
      "Properties" : {
        "RouteTableId" : { "Ref" : "PublicRouteTable" },
        "DestinationCidrBlock" : "0.0.0.0/0",
        "GatewayId" : { "Ref" : "InternetGateway" }
      }
    },

    "DBSubnetGroup" : {
      "Type" : "AWS::RDS::DBSubnetGroup",
      "Properties" : {
        "DBSubnetGroupDescription" : "This is a privateSubnet",
        "SubnetIds": [{"Ref": "PrivateSubnet1"},{ "Ref" : "PrivateSubnet2" }]
      }
    },

    "WebServerSecurityGroup" : {
      "Type" : "AWS::EC2::SecurityGroup",
      "Properties" : {
        "GroupDescription" : "Enable HTTP access via port 80 locked down to the ELB and SSH access",
        "SecurityGroupIngress" : [
          { "IpProtocol" : "tcp", "FromPort" : "80", "ToPort" : "80", "CidrIp" : "0.0.0.0/0"},
          {"IpProtocol" : "tcp", "FromPort" : "22", "ToPort" : "22", "CidrIp" : { "Ref" : "SSHLocation"}
          } ],
        "VpcId" : { "Ref" : "VPC" }
      }
    },

    "DBSecurityGroup" : {
      "Type" : "AWS::EC2::SecurityGroup",
      "Properties" : {
        "GroupDescription" : "Enable WebServer access via port 3306",
        "SecurityGroupIngress" : [
          {"IpProtocol" : "tcp", "FromPort" : "3306", "ToPort" : "3306", "SourceSecurityGroupId" : { "Ref" : "WebServerSecurityGroup"}
          } ],
        "VpcId" : { "Ref" : "VPC" }
      }
    },

    "InboundPublicNetworkAclEntry" : {
      "Type" : "AWS::EC2::NetworkAclEntry",
      "Properties" : {
        "CidrBlock" : "0.0.0.0/0",
        "Egress" : false,
        "NetworkAclId" : { "Ref" : "NetworkAcl" },
        "Protocol" : "-1",
        "RuleAction" : "allow",
        "RuleNumber" : "100"
      }
    },

    "OutboundPublicNetworkAclEntry" : {
      "Type" : "AWS::EC2::NetworkAclEntry",
      "Properties" : {
        "CidrBlock" : "0.0.0.0/0",
        "Egress" : true,
        "NetworkAclId" : { "Ref" : "NetworkAcl" },
        "Protocol" : "-1",
        "RuleAction" : "allow",
        "RuleNumber" : "100"
      }
    },

    "PublicSubnet1NetworkAclAssociation" : {
      "Type" : "AWS::EC2::SubnetNetworkAclAssociation",
      "Properties" : {
        "SubnetId" : { "Ref" : "PublicSubnet1" },
        "NetworkAclId" : { "Ref" : "NetworkAcl" }
      }
    },

    "PublicSubnet2NetworkAclAssociation" : {
      "Type" : "AWS::EC2::SubnetNetworkAclAssociation",
      "Properties" : {
        "SubnetId" : { "Ref" : "PublicSubnet2" },
        "NetworkAclId" : { "Ref" : "NetworkAcl" }
      }
    },

    "VPCDHCPOptionsAssociation": {
      "Type": "AWS::EC2::VPCDHCPOptionsAssociation",
      "Properties": {
        "VpcId": {
          "Ref": "VPC"
        },
        "DhcpOptionsId": {
          "Ref": "DHCPOptions"
        }
      }
    },

    "Public1SubnetRouteTableAssociation" : {
      "Type" : "AWS::EC2::SubnetRouteTableAssociation",
      "Properties" : {
        "SubnetId" : { "Ref" : "PublicSubnet1" },
        "RouteTableId" : { "Ref" : "PublicRouteTable" }
      }
    },

    "Public2SubnetRouteTableAssociation" : {
      "Type" : "AWS::EC2::SubnetRouteTableAssociation",
      "Properties" : {
        "SubnetId" : { "Ref" : "PublicSubnet2" },
        "RouteTableId" : { "Ref" : "PublicRouteTable" }
      }
    },

    "ELB": {
      "Type": "AWS::ElasticLoadBalancing::LoadBalancer",
      "DependsOn" : [ "PublicSubnet1", "PublicSubnet2" ],
      "Properties": {
        "CrossZone" : "true",
        "SecurityGroups": [ { "Ref": "ELBSecurityGroup" } ],
        "Subnets": [ {"Ref": "PublicSubnet1"},{ "Ref" : "PublicSubnet2" } ],
        "Listeners": [ {
          "LoadBalancerPort": "80",
          "InstancePort": "80",
          "Protocol": "HTTP"
        } ],
        "HealthCheck": {
          "Target": "HTTP:80/",
          "HealthyThreshold": "10",
          "UnhealthyThreshold": "2",
          "Interval": "30",
          "Timeout": "5"
        }
      }
    },

    "ELBSecurityGroup": {
      "Type": "AWS::EC2::SecurityGroup",
      "Properties": {
        "GroupDescription" : "Allow inbound access to the ELB",
        "VpcId": { "Ref": "VPC" },
        "SecurityGroupIngress": [ {
          "IpProtocol": "tcp",
          "FromPort": "80",
          "ToPort": "80",
          "CidrIp": "0.0.0.0/0"
        } ],
        "SecurityGroupEgress": [ {
          "IpProtocol": "tcp",
          "FromPort": "80",
          "ToPort": "80",
          "CidrIp": "0.0.0.0/0"
        } ]
      }
    }
  },

  "Description": "OpsWorks Tutorial template",
  "Outputs" : {
    "ELBIdentifier" : {
      "Value" : { "Ref" : "ELB" },
      "Description" : "ELB Identifier"
    }
  }
}
# スタックの作成
aws cloudformation create-stack --stack-name opsworks-vpc-elb --template-body file://`pwd`/Opsworks11_sample.json \
--parameters ParameterKey=KeyName,ParameterValue=YOUR_KEY_NAME ParameterKey=SSHLocation,ParameterValue=xxx.xxx.xxx.xxx/32

3. Chef11のチュートリアルを体験

内容は下記です。

Chef 11 シンプルで機能的な PHP アプリケーションサーバーのLinux スタック

① スタックを新規作成
項目 入力値
Stack MyStack
VPC OpsWorksVPC
Default SSH key いつものKey
Custom Cookbook git://github.com/amazonwebservices/opsworks-example-cookbooks.git

f:id:moqrin3:20190126233336p:plain

② レイヤーを追加

PHP,MySQLともにPublicIPとSecurityGropを付与しましょう。

MySQL root user passwordは d1zethv0sm

f:id:moqrin3:20190126233008p:plain

f:id:moqrin3:20190126233033p:plain

f:id:moqrin3:20190126233107p:plain

f:id:moqrin3:20190126233130p:plain

インスタンスを追加

MySQLレイヤーはPublicサブネットで作成します。

f:id:moqrin3:20190126233445p:plain

④ Appsの追加
項目 入力値
Name SimplePHPApp
Document root web
Git git://github.com/awslabs/opsworks-demo-php-simple-app.git
Branch/Revision version2
Data source type OpsWorks
Database name

f:id:moqrin3:20190126233509p:plain

インスタンスを起動
⑥ Deployにライフサイクルイベント設定

各レイヤーのRecipesから設定

  • phpapp::dbsetup
  • phpapp::appsetup

f:id:moqrin3:20190126233717p:plain

f:id:moqrin3:20190126233743p:plain

⑦ Appsのデプロイ

f:id:moqrin3:20190126233801p:plain

f:id:moqrin3:20190126233822p:plain

⑧ ELBレイヤーを追加

f:id:moqrin3:20190126233843p:plain

f:id:moqrin3:20190126233923p:plain

⑨ 確認

f:id:moqrin3:20190126233939p:plain

消すときは、インスタンス->Apps->スタック。

4. 宿題

ま、とりあえずChefから学習しないとですねー。

参考:

AWS OpsWorks とは

AWS Black Belt / AWS OpsWorks