想ひ出29: AWS/Elastic Beanstalkに入門する/2
おはようございます、moqrinです。
前回の続きです。
今回のテーマはこちらです。
ElasticBeanstalkでLaravelアプリケーションをRDSと接続して設定する
以下、コンソールベースでゴシゴシ作成するパターンと、コマンドで叩いて作成するパターンで進めます。(途中、ズルしてコンソールも使います。。)
目次
1. ElasticBeanstalkでLaravelアプリケーションをRDSと接続して設定する(コンソールベース)
2. ElasticBeanstalkでLaravelアプリケーションをRDSと接続して設定する(EB CLIベース)
3. 宿題
1. ElasticBeanstalkでLaravelアプリケーションをRDSと接続して設定する(コンソールベース)
それでは進めていきます。なお、RDSにMySQLのDBがあることが前提です。
① アプリケーションの作成
② PHPで環境を作成
③ カスタム設定
ネットワークをカスタムVPCにします。
色々便利なので、キーペアを設定しておきましょう。
環境変数の追加やドキュメントルートを設定しておきましょう。
そしたら作成します。
思いっきりエラー出てますが、無視していいです。
④ セキュリティグループの編集
RDSへ接続するセキュリティグループ(以下SG)にEBのSGを追加します。
⑤ プロジェクト以下、public/index.phpに接続の情報を追記する
DB接続がちゃんと出来ているか確認します。
⑥vender以外の内容をzipにしてアップロードする
※ なお、ディレクトリをそのままzipするとパスがおかしくなっちゃうので注意。
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を追加します。(環境がエラーだって怒ってますが無視します。)
(eb deployでもいいのだけども)とりあえず、Vender以外のソースをzipにしてアップロードします。
はい、成功
じゃ見に行きましょう。ちなみに、飛び先は404なので、/passportsを飛び先につけます。
/passports/createで新規作成です。作成します。
はい、ちゃんと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
想ひ出28: AWS/Elastic Beanstalkに入門する/1
おはようございます、moqrinです。
引き続き、今更感満載でElastic Beanstalkに入門(復習?)したので、個人的まとめ1です。
内容としては、公式リファレンス抜粋です。
目次
2. 構成要素
3. デプロイ方式
4. 環境設定のカスタマイズ
5. モニタリングの方法
1. Elastic Beanstalkとは
定番構成の構築・アプリデプロイの自動化サービス
Java, PHP, Ruby, Python, Node.js, .NET, Docker, Goに対応
定番構成
- ウェブサーバー環境
- ワーカー環境
2. 構成要素
構成要素 | 機能 |
---|---|
アプリケーション | Elastic Beanstalkトップレベルの管理単位 |
バージョン | デプロイ可能なアプリケーション |
環境 | 各環境(ウェブサーバ、ワーカー) に応じて構築されるインフラ環境 |
環境設定 | インスタンスタイプやAutoScalingなどの環境に関連するパラメータ設定 |
3. デプロイ方式
出典: AWS Elastic Beanstalk 環境へのアプリケーションのデプロイ
4. 環境設定のカスタマイズ
- 環境作成時に直接設定(EB CLI or マネジメントコンソール)
- 保存済み設定(起動中の環境や過去保存した環境設定を再利用できる)
- .ebextensions
.ebextensionsとは
- 環境に対する様々な操作を柔軟に自動化 & 集約可能
- ソースルートで .ebextensions フォルダに設定ファイルを追加する
5. モニタリング
- EB CLIでモニタリング(eb health -r)
- EB マネージメントコンソール
- CloudWatch Logsを使ってログ監視: CloudWatch Logsへの書き込み権限はIAM Role
では次回、Laravelで実践しましょう。
参考:
想ひ出27: AWS/CodePipelineに入門する/2
おはようございます、moqrinです。
前回の続きです。
当記事はCodeDeployを設定してCodePipelineを実行して確認まで、となります。
全部で4ステップで、当記事は3ステップから行います。
目次
3. AWS CodeDeploy でアプリケーションを作成する
6. 宿題
1. インスタンスに必要なIAMロールを設定
- S3からCodeDeployエージェントをインストールするために新しい IAM ロールを作成
# ポリシー { "Version": "2012-10-17", "Statement": [ { "Action": [ "s3:Get*", "s3:List*" ], "Effect": "Allow", "Resource": "*" } ] }
元々のAWSCodeCommitFullAccessと上記を併せて、"CodePipelineForEC2Role"(名前は何でもいいけど)を作成。 こちらをインスタンスに付与します。
- 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
# エージェントを確認 service codedeploy-agent status
インスタンスは準備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 でアプリケーションを作成する
① アプリケーションを作成
② デプロイグループの作成
ま、適当に。
4. CodePipelineを作成する
ソースはCodeCommit
今回ビルドはしないので、スキップ
そしてデプロイ
5. CodeCommit リポジトリにPushしてみる
早速Pushして確認。
ついでに、タイトルとか変えてみる。
CodePipeline上でも確認
表示
OK.
何かエラーが有った場合はこの辺を見よう。
tail -f /var/log/aws/codedeploy-agent/xxxx.log tail -f /opt/codedeploy-agent/deployment-root/deployment-logs/xxxx.log
6. 宿題
かなり雑なやり方だったので、もうちょっと整備した方が宜しいですね。。。
参考:
チュートリアル: シンプルなパイプラインを作成する (AWS CodeCommit リポジトリの場合)
想ひ出26: AWS/CodePipelineに入門する/1
おはようございます、moqrinです。
いつもの如く、今更感満載ですがCodePipelineに入門したので、そのまとめ1です。
当記事はCodeCommitリポジトリを作成して、EC2インスタンスにクローンして確認まで、となります。
次回がCodeDeployを利用したCodePipelineの体験となります。
素材としては、Flaskのチュートリアルブログを使います。
全部で4ステップで、当記事は2ステップまでを行います。
目次
1. CodeCommitリポジトリ作成してHttpsで接続/ローカル
3. 表示までを確認
4. 宿題
1. CodeCommitリポジトリ作成してHttpsで接続/ローカル
前提
① CodeCommitでリポジトリを作成
早速作成します。
② 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
問題なさそうなら、適当な場所にリポジトリをクローンしちゃいます。
③ ローカルからファイルを追加する
ちなみに、「macOS を使用している場合は、HTTPS を使用して AWS CodeCommit リポジトリに初めて接続すると、約 15 分後に後続のアクセスが失敗します。」とか書いているので、いきなりエラーが発生した場合にご留意下さい。いきなりエラーが出たとき、ワタクシはキョドりました・・・
次はサーバーでの対応に進みます。
2. Httpsで接続してGitクローン/インスタンス
① AWSCodeCommitFullAccessを付与してインスタンスサーバーを起動する
② 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
表示確認
4. 宿題
あれ、AutoScalingとCodeDeploy,CodePipelineってどういう感じになるか確認しなきゃ。
参考:
AWS CLI 認証情報ヘルパーを使用して Linux, macOS, or Unix 上で AWS CodeCommit リポジトリへの HTTPS 接続のセットアップステップ
# 想ひ出25: AWS/OpsWorksに入門する/1
おはようございます、moqrinです。
今回も今更感満載ですが、OpsWorksをやってみました。
これもしばらく触らないと忘れるため、個人的後日振り返り用でございます。
OpsWorksはあまり人気がないのか皆さまの記事がない印象でした。
5年近く前のハンズオンとかやってみたんですが、何かうまく出来なかったこと、
Chefともあまり馴染みがないので、、CloudFormationで下準備して、
以前のバージョンChef11のチュートリアルを体験しました。
また後日、Chef12で進めるつもりでございます。
目次
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 SDK、AWS 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 |
② レイヤーを追加
PHP,MySQLともにPublicIPとSecurityGropを付与しましょう。
MySQL root user passwordは d1zethv0sm
③ インスタンスを追加
MySQLレイヤーはPublicサブネットで作成します。
④ 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 |
⑤ インスタンスを起動
⑥ Deployにライフサイクルイベント設定
各レイヤーのRecipesから設定
- phpapp::dbsetup
- phpapp::appsetup
⑦ Appsのデプロイ
⑧ ELBレイヤーを追加
⑨ 確認
消すときは、インスタンス->Apps->スタック。
4. 宿題
ま、とりあえずChefから学習しないとですねー。