多分わかりやすいCloudFormation入門とチュートリアル
多分わかりやすいCloudFormation入門とチュートリアル:
Serverのリソース管理(WebサーバーとかDBサーバーとかのマシン管理)ってみなさん何で管理していますか?
ただCloudFormationをいざ始めてみようとすると
簡単にいうとサービス単位とかでAWSリソースを管理する単位のことです。
例でいうとWEBサービスを作りたいと思った時に大抵の場合下記のような構成になると思います。
(最近はDockerっていう選択もありますが)
先程のスタックでサービス単位で管理をするとどのサービスでも共通して使用するものがあると思います。
例として
(例: スタックAで定義したセキュリティグループはスタックBで重複管理することはできません)
これを実現するためにはエクスポート機能を使用して値をエクスポートして共有します。
プログラム的に言うとグローバル変数を宣言するイメージに近いです。
よくある構成パターンですね。
かつ今回はテスト環境と本番環境で別々のリソース管理をしてみましょう。
管理するAWSリソースを定義するテンプレートです。(yml)
まずはこんな形のymlを用意しましょう
そのまんまです。
ではサービス名でも定義してみましょう
型指定とDefault値を指定できます。
詳しいオプションは
公式ドキュメント Parametersを参照してください。
EC2やRDS、セキュリティグループ等AWSで使うサービスの定義をすべてしていきます。
ではまずはWEBサーバーを作成するにあたってのAWSリソースで最低限必要なものは下記です。
上から順番に説明していきます
リソースの名前です。任意の名前をつけてください。
なんのリソースを配置するかです。
名前がわからない場合はgoogleさんに「cloudformation EC2」とかでぐぐればgoogleさんが教えてくれます。
指定したリソースのプロパティーです。プロパティがわからない場合は
cloudformation EC2」とかでぐぐればgoogleさんが教えてくれます。
CloudFormationでは組込み関数が用意されています。
公式CloudFormation 組込み関数
書き方に少し癖があるのですが下記を覚えてしまえば難しくないです。
例えばショート記法を使わない場合でRefを使用したい場合だと
と書きます。
:を段落区切りを表すyamlの場合この方式で書くと少々可読性が悪くなります。
なのでショート記法で書いている人のほうが多いです。
でパラメーターの値を参照できます。
で配置するリソースの返り値を取得できます。
リソース名の返り値は 「cloudformation EC2 リソース返り値」とかでぐぐれば.....
大概の場合リソースを参照したい場合は乱暴に
と宣言すればよしなに参照できます。
Parameterと文字列のテンプレートリテラルです。
文字列 + Parameterで値を作成したいときにつかってください。
ではAWS cliを使ってCloudFormationを実際に動かしてみましょう。
ここまでのtemplateファイルは下記です。
template.yml
もし一回目にエラーになった場合は2回目以降は下記です。
EC2のGUIを確認してください。t2.microで
セキュリティグループもできていますね。
ここまでできたら要領は把握したのでRDSも作ってみましょう
ここまでのtemplate.ymlは下記です
template.yml
ではコマンドを実行してみましょう。
RDSとEC2が作成されてそれぞれのセキュリティグループが作成されています。
困りましたね。。。
出来上がったEC2の内容を確認できません。
ですがセキュリティグループは慎重にやらないと事故のもとです。
そういった場合に便利なcreate-change-setというものがあります。
create stackやupate stackのようにtemplateやパラメーターをスタックに送信しますが
リソースの変更を行わずにリソース変更部分の差分を出してくれます。
dry-runをイメージしてもらえるとわかりやすいと思います。
では実際にやってみましょう。
template.ymlに追記しましょう
ここまでのtemplateです。
template.yml
awscliの
aws cli create-change-set
AWS CloudformationのGUIのスタックの項目を開いてください。
変更セットの部分に先程実行した
の項目が出てきます。
このリンクを開くとリソースの変更内容がでてきます。
変更した内容がEC2のセキュリティグループだけなのがわかりますね。
では変更セットの詳細画面右上の実行ボタンを押して反映させてみましょう。
スタックの状況が
になったら正しく反映できています。
DBに入れました。
これでCloudFormationの流れがつかめてきたと思います。
では最後にCloudFormationの削除を実行してみましょう。
CloudFormationで定義されたリソースの削除は非常に簡単にできます。
これだけです。
定義したリソースすべてをキレイサッパリ削除してくれます。
リソースの消し忘れがなくて良いですね!!
今まで作成したものはtest環境用のリソースです。
そこでproduction用に作るやり方を紹介します。
今回は一つのテンプレートで変数のみを変更して複数のenv環境を作るやり方です。
Prefixの値を上書きしましょう。
こうすることによって
コマンドはいままで --parametersで指定していた
コマンドは下記です。
(stack-nameはtesting環境と違う名前で登録してください。CloudFormationがtesting環境のリソースを上書きます)
一つのテンプレートで複数環境ができました。
ちょっとドキュメントを読んだだけではわかりにくいCloudFormationですが
手を動かしてしまえば意外とシンプルです。
それでは楽しい?CloudFormationライフを!!
Serverのリソース管理(WebサーバーとかDBサーバーとかのマシン管理)ってみなさん何で管理していますか?
- Ansible
- AWS CLI(Shell)
- etc....
ただCloudFormationをいざ始めてみようとすると
- ドキュメントの量が膨大
- 謎のyml記法がある(DSL的な)
対象者
- AWSを使っている
- CloudFormationってナニソレ美味しいの?って人
- サーバーのリソース管理方法を選んでいる人
事前に必要なもの
- aws cli
- macな方は黙って
brew install awscli
と打とう
- macな方は黙って
やらないこと
- ポチポチとGUIでCloudFormationを作らない
CloudFormationでまず知っておくことその1 スタック
簡単にいうとサービス単位とかでAWSリソースを管理する単位のことです。
例でいうとWEBサービスを作りたいと思った時に大抵の場合下記のような構成になると思います。
(最近はDockerっていう選択もありますが)
- WEBサーバー(EC2)
- DBサーバー(RDS)
- ロードバランサー(ELB)
- セキュリティグループ
- Route53
- etc....
CloudFormationでまず知っておくことその2 エクスポート
先程のスタックでサービス単位で管理をするとどのサービスでも共通して使用するものがあると思います。
例として
- 共通のセキュリティグループ
- VPC
(例: スタックAで定義したセキュリティグループはスタックBで重複管理することはできません)
これを実現するためにはエクスポート機能を使用して値をエクスポートして共有します。
プログラム的に言うとグローバル変数を宣言するイメージに近いです。
WEBサーバー x DBサーバー を作るチュートリアル
よくある構成パターンですね。かつ今回はテスト環境と本番環境で別々のリソース管理をしてみましょう。
ディレクトリを掘る
{path/to/dir}
はお好みのディレクトリを指定してください。cd {path/to/dir} mkdir -p cf-tutorial/parameters touch cf-tutorial/template.yml touch cf-tutorial/parameters/{production,testing}.json echo '[]' >> cf-tutorial/parameters/{production,testing}.json
リソースを定義するためのTemplateを書く
管理するAWSリソースを定義するテンプレートです。(yml)まずはこんな形のymlを用意しましょう
template.yml
AWSTemplateFormatVersion: '2010-09-09' Description: cf tutorial stack Parameters: # Parameters以下に変数を定義する Resources: # Resources以下に管理したいResourceを管理する Outputs: # エクスポートしたい値を書く
Parameters (変数)
そのまんまです。ではサービス名でも定義してみましょう
(抜粋)template.yml
Parameters: Prefix: Type: String Default: testing Description: Prefix Name ServiceName: Type: String Default: cf-tutorial
詳しいオプションは
公式ドキュメント Parametersを参照してください。
Resouces
EC2やRDS、セキュリティグループ等AWSで使うサービスの定義をすべてしていきます。ではまずはWEBサーバーを作成するにあたってのAWSリソースで最低限必要なものは下記です。
- SecurityGroup
- EC2
(抜粋)template.yml
Resources: Ec2SecurityGroupApp: Type: "AWS::EC2::SecurityGroup" Properties: GroupName: !Sub "${Prefix}_${ServiceName}_app" GroupDescription: "web server security group" VpcId: "{your VPCID}" SecurityGroupIngress: - IpProtocol: tcp FromPort: 80 ToPort: 80 CidrIp: "0.0.0.0/0" Tags: - Key: Name Value: !Sub "${Prefix}_${ServiceName}_app" Ec2InstanceServer: Type: "AWS::EC2::Instance" Properties: AvailabilityZone: "ap-northeast-1c" # AmazonLinuxを指定しています ImageId: "ami-06cd52961ce9f0d85" InstanceType: "t2.micro" KeyName: "your キーペア名" SecurityGroupIds: - !Ref Ec2SecurityGroupApp BlockDeviceMappings: - DeviceName: /dev/xvda Ebs: VolumeSize: 8 VolumeType: gp2 Tags: - Key: Name Value: !Sub "${Prefix}_${ServiceName}_app"
Ec2SecurityGroupApp, Ec2InstanceServer (ResourceKeyName)
リソースの名前です。任意の名前をつけてください。
Type
なんのリソースを配置するかです。名前がわからない場合はgoogleさんに「cloudformation EC2」とかでぐぐればgoogleさんが教えてくれます。
Properties:xxxxxxxx
指定したリソースのプロパティーです。プロパティがわからない場合はcloudformation EC2」とかでぐぐればgoogleさんが教えてくれます。
!Sub,!Ref (CloudFormationの組込関数)
CloudFormationでは組込み関数が用意されています。公式CloudFormation 組込み関数
書き方に少し癖があるのですが下記を覚えてしまえば難しくないです。
!{関数名}はショート記法
例えばショート記法を使わない場合でRefを使用したい場合だとSecurityGroupIds: - Fn::Ref: Ec2SecurityGroupApp
:を段落区切りを表すyamlの場合この方式で書くと少々可読性が悪くなります。
なのでショート記法で書いている人のほうが多いです。
Ref
!Ref {パラメーター名}
!Ref {リソース名}
リソース名の返り値は 「cloudformation EC2 リソース返り値」とかでぐぐれば.....
大概の場合リソースを参照したい場合は乱暴に
!Ref {リソース名}
Sub
Parameterと文字列のテンプレートリテラルです。文字列 + Parameterで値を作成したいときにつかってください。
実際に作ってみる
ではAWS cliを使ってCloudFormationを実際に動かしてみましょう。ここまでのtemplateファイルは下記です。
template.yml
aws cloudformation create-stack \ --stack-name {任意のスタック名} \ --template-body file://`pwd`/template.yml \ --parameters file://`pwd`/parameters/testing.json
aws cloudformation update-stack \ --stack-name {任意のスタック名} \ --template-body file://`pwd`/template.yml \ --parameters file://`pwd`/parameters/testing.json
{Prefix}-{ServiceName}_app
というサーバーが立ち上がっているのが確認できます。セキュリティグループもできていますね。
RDSを作成してみる
ここまでできたら要領は把握したのでRDSも作ってみましょう(抜粋)template.yml
# RDSのセキュリティグループ RdsSecurityGroupApp: Type: "AWS::EC2::SecurityGroup" Properties: GroupName: !Sub "${Prefix}_${ServiceName}-rds" GroupDescription: "dbserver security group" VpcId: "{your VPCID}" SecurityGroupIngress: - IpProtocol: tcp FromPort: 3306 ToPort: 3306 SourceSecurityGroupName: !Sub "${Prefix}_${ServiceName}_app" Tags: - Key: Name Value: !Sub "${Prefix}_${ServiceName}-rds" RdsInstace: Type: "AWS::RDS::DBInstance" DeletionPolicy: Delete Properties: DBInstanceIdentifier: !Sub "${Prefix}-${ServiceName}-db" AvailabilityZone: "ap-northeast-1c" DBInstanceClass: "t2.small" AllocatedStorage: 6 StorageType: gp2 VPCSecurityGroups: - !Ref RdsSecurityGroupApp Engine: MySQL EngineVersion: 5.7.23 DBName: cf-tutorial MasterUsername: cf-tutorial MasterUserPassword: {your password} Tags: - Key: Name Value: !Sub "${Prefix}_${TagServiceGroupName}-db-app-${CFVersion}"
template.yml
ではコマンドを実行してみましょう。
aws cloudformation update-stack \ --stack-name {任意のスタック名} \ --template-body file://`pwd`/template.yml \ --parameters file://`pwd`/parameters/testing.json
EC2のセキュリティグループに22番ポートが開いていなくてsshログインできないぽよ。。。。
困りましたね。。。出来上がったEC2の内容を確認できません。
ですがセキュリティグループは慎重にやらないと事故のもとです。
そういった場合に便利なcreate-change-setというものがあります。
create change setとは?
create stackやupate stackのようにtemplateやパラメーターをスタックに送信しますがリソースの変更を行わずにリソース変更部分の差分を出してくれます。
dry-runをイメージしてもらえるとわかりやすいと思います。
では実際にやってみましょう。
EC2インスタンスにSSHポートを追加する
template.ymlに追記しましょう(抜粋)template.yml
Resources: Ec2SecurityGroupApp: Type: "AWS::EC2::SecurityGroup" Properties: GroupName: !Sub "${Prefix}_${ServiceName}_app" GroupDescription: "web server security group" VpcId: "{your VPCID}" SecurityGroupIngress: - IpProtocol: tcp FromPort: 80 ToPort: 80 CidrIp: "0.0.0.0/0" # 追加内容 - IpProtocol: tcp FromPort: 22 ToPort: 22 CidrIp: "0.0.0.0/0" Tags: - Key: Name Value: !Sub "${Prefix}_${ServiceName}_app"
template.yml
awscliの
create-change-set
を実行します。aws cli create-change-set
aws cloudformation create-change-set \ --stack-name {任意のスタック名} \ --change-set-name add-securitey-group-ssh \ --template-body file://`pwd`/template.yml \ --parameters file://`pwd`/parameters/testing.json
変更セットの部分に先程実行した
change-set-name
このリンクを開くとリソースの変更内容がでてきます。
変更した内容がEC2のセキュリティグループだけなのがわかりますね。
では変更セットの詳細画面右上の実行ボタンを押して反映させてみましょう。
スタックの状況が
UPDATE_COMPLETE
RDSに接続できるか確認してみましょう
ssh -i ~/.ssh/{your キーペア名} -p22 ec2-user@{Your IP Adress} sudo yum install -y mysql-devel mysql -u cf_tutorial -p -h {your rds host} Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 9 Server version: 5.7.23-log Source distribution Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | cf_tutorial | | innodb | | mysql | | performance_schema | | sys | +--------------------+ 6 rows in set (0.00 sec)
スタックの掃除をしてみましょう
これでCloudFormationの流れがつかめてきたと思います。では最後にCloudFormationの削除を実行してみましょう。
CloudFormationで定義されたリソースの削除は非常に簡単にできます。
aws cloudformation delete-stack --stack-name {任意のスタック名}
定義したリソースすべてをキレイサッパリ削除してくれます。
リソースの消し忘れがなくて良いですね!!
Parameterのオーバーライドによるtest環境,production環境を別々に作る
今まで作成したものはtest環境用のリソースです。そこでproduction用に作るやり方を紹介します。
今回は一つのテンプレートで変数のみを変更して複数のenv環境を作るやり方です。
production.jsonを変更する
Prefixの値を上書きしましょう。production.json
[ { "ParameterKey": "Prefix", "ParameterValue": "production" } ]
template.yml
で定義されているParameter Prefixをオーバーライドすることができます。コマンドはいままで --parametersで指定していた
testing.json
を production.json
に変更します。コマンドは下記です。
(stack-nameはtesting環境と違う名前で登録してください。CloudFormationがtesting環境のリソースを上書きます)
aws cloudformation create-stack \ --stack-name {任意のスタック名} \ --template-body file://`pwd`/template.yml \ --parameters file://`pwd`/parameters/prodcution.json
最後に
ちょっとドキュメントを読んだだけではわかりにくいCloudFormationですが手を動かしてしまえば意外とシンプルです。
それでは楽しい?CloudFormationライフを!!
コメント
コメントを投稿