notebook

都内でWEB系エンジニアやってます。

cloudformationを使ってみる

1からインフラを構築する機会があったのでどうせなら次やるときも楽できるようにある程度定義ファイルを用意することにしました

terraformと迷ったのですがterraformは以前個人的に使ったことがあったので今回はcloudformationを使うことにしました

yaml対応もされたようですしね

デザイナーでごにょごにょしてテンプレート生成するか、すでに誰かが作っているであろうテンプレートを使うか、1から使うか迷ったものの調べていて思ったのはなんかよくわからん!ということだけだったので1から作ってみて感覚をつかむことにしました

権限の追加

cliから実行するためにIAMロールに追加します

AWS Identity and Access Management によるアクセスの制御 - AWS CloudFormation

docs.aws.amazon.com

cloudformation:*とかで大丈夫ですが、ElasticacheやRDSなどを追加する場合は別途で権限が必要なので必要な場合は加えておく

簡単なサンプルを動作させてみる

まずは感じをつかむためVPCのみ作ってみます

  • sample.template.yml
AWSTemplateFormatVersion: '2010-09-09'
Resources:
  myVPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
      EnableDnsSupport: 'false'
      EnableDnsHostnames: 'false'
      InstanceTenancy: default
      Tags:
      - Key: Name
        Value: Sample
aws cloudformation create-stack \
  --stack-name sample \
  --template-body file:///home/vagrant/sandbox/cfn/sample.template.yml

{
    "StackId": "arn:aws:cloudformation:ap-northeast-1:111111111111:stack/sample/e97ffe10-4a09-11e7-8ce1-50a68a175a82"
}

マネジメントコンソールからVPCが作られたことを確認します

f:id:swfz:20170618043810p:plain

myVPCが論理IDということでこれを元にリソースを管理しているようです

stackの更新

先ほど作ったテンプレートに少し追加して更新してみます

  • sample.template.yml
AWSTemplateFormatVersion: '2010-09-09'
Resources:
  myVPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
      EnableDnsSupport: 'false'
      EnableDnsHostnames: 'false'
      InstanceTenancy: default
      Tags:
      - Key: Name
        Value: SampleVPC

簡単なところでタグのNameをSample -> SampleVPCに変更してみました

aws cloudformation create-stack \
  --stack-name sample \
  --template-body file:///home/vagrant/sandbox/cfn/sample.template.yml

マネジメントコンソールから確認します

変更する項目によってはidが変わってしまう(delete and createになってしまう)ようなので気をつける必要があります

ドキュメントに変更時の挙動が書いてあるので確認すればOKですね

f:id:swfz:20170618043832p:plain

リソース一覧

リソースの一覧が見れるのでcloudformationで作ったものは判断つきますね

デフォルトでcloudformationでつけたタグ以外に色々タグがつくようです(論理IDとか)

f:id:swfz:20170618043847p:plain

リソースの数は。。。35個!!(かもしれない)

引数

Parameters:以下でパラメータを指定できます

リージョンが変わっても対応できるようavailability zoneを指定できるようにしてみます

  • sample.template.yml
AWSTemplateFormatVersion: '2010-09-09'
Parameters:
  AZ1Parameter:
    Type: String
    Default: 'ap-northeast-1a'
    Description: select availability zone
  AZ2Parameter:
    Type: String
    Default: 'ap-northeast-1c'
    Description: select availability zone

Resources:
....
  public0A:
    Type: "AWS::EC2::Subnet"
    Properties:
      AvailabilityZone:
        Ref: AZ1Parameter
      CidrBlock: 10.0.0.0/24
      Tags:
      - Key: Project
        Value: Sample
      - Key: Name
        Value: 'Public 0a'
      VpcId:
        Ref: myVPC
....

AZ1Parameterで値を渡しています

実行時は--parametersに渡してあげます

./aws cloudformation update-stack \
  --stack-name sample \
  --template-body file:///home/sawafuji.yuya/sandbox/cfn/sample.template.yml \
  --parameters ParameterKey=AZ1Parameter,ParameterValue=ap-northeast-1a \
  ParameterKey=AZ2Parameter,ParameterValue=ap-northeast-1c

ここら辺は理解しやすいですね

部分的に変数を扱う

下記参考にしました

【小ネタ】CloudFormationで文字列内に変数を入れる。(YAML版) | Developers.IO

dev.classmethod.jp

設定例としてプロジェクトネーム+何かしらみたいな場合

myVPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
      EnableDnsSupport: 'false'
      EnableDnsHostnames: 'false'
      InstanceTenancy: default
      Tags:
      - Key: Name
      Value: !Sub ${ProjectNameParameter}WithB

こんな感じで扱うことが出来ます

f:id:swfz:20170618043920p:plain

感想

大体どの記事もこれテンプレートです!みたいなのばかりでいきなり大量の記述量がドンと出てくるのでどうしよう。。。と思っていたのですが一つづつやっていくことで理解が出来ました

最初がとっつきにくいだけでドキュメントもしっかりあるしある程度エラーの場合も原因が書かれているのでとても書きやすかったです

書いてる時はマネジメントコンソールからぽちぽちやっているのとあんまり変わらない気がするのでドキュメントとにらめっこしながらこつこつやっていけそうな感じですね

ちなみにドキュメントは下記

AWS CloudFormation とは - AWS CloudFormation

docs.aws.amazon.com

結局こつこつ書いていくと気づけば500行を超えるテンプレートになっていてこれがテンプレートです!になるのは納得がいきました

色々書いていくと記述が結構冗長になる感じがするのですがスタック間参照を使ったりすることで解決できるようです

今回はそこまで試していませんが一旦叩くだけでサービス開始直前までのインフラ構築が出来るテンプレートを作ることが出来たので良かったです

気になった点

気になったのはロールバックやアップデートなど何かしらの原因で詰まってしまうことがあるようです。

しかも詰まってしまった場合は何も進まず、場合によっては対象リソースの変更などもできない。サポートセンター行きといった解決策しかなさそうなのがちょっと微妙だなと思いました。

うっかり変な変更をしようとしてしまってサービス止まったままサポートセンターへ問い合わせなんてなったら目も当てられませんw

そう考えると運用までずっと使うのは少し気がひけるなーという印象で新規の構築一発目などで使うのがいいのかなといったイメージでした

とはいうものの定義書くだけでデザイナー経由で図に落とし込めるのはとても便利ですね

途中経過ですがこんな図になりました

f:id:swfz:20170618043938p:plain