CloudFormationを勉強したので聞いて欲しい
CloudFormationへようこそ
この記事の対象者は:
AWSは触ったことあるけどCloudFormationは初めての方向けです。
あんまり向いていない対象者:
AWSを触ったことがない人
この記事の内容
僕個人が結構つまづいたポイントをまとめて初学者の学習スピードを縮めてもらえたらなと思います。
まずCloudFormationとは?
AWS CloudFormation は、クラウド環境で AWS とサードパーティ製アプリケーションリソースのモデリングおよびプロビジョニングをする際の、共通的な手法を提供します。AWS CloudFormation では、プログラミング言語またはシンプルなテキストファイルを使用して、あらゆるリージョンとアカウントでアプリケーションに必要とされるすべてのリソースを、自動化された安全な方法でモデル化し、プロビジョニングできます。これは、AWS とサードパーティ製のリソースに真に単一のソースを与えます。
要するに
「AWSのインフラ構成をコード化しましょう」
これにつきます。
CloudFormationを始めるに当たって
1.構成図を考える
CloudFormationを始めるに当たって必要なものがあります。
それが既存のAWS構成です。
よくCloudFormationの記事でほとんどクラスメソッドさんの記事なのですが、
こういった記事によくあるこのAWSの構成図これがとても大事でした。
ちなみに僕は台本と読んでいます。
ユーザがなぜこの構成が欲しいのか?を検討することにより、実現できなかったとしても別の方法が考えられると思ったからです。
2.実際にマネジメントコンソールで作ってみる
最初は簡単なものからでいいと思います。
EC2のインスタンスタイプを変更するなりEBSのサイズを変更するなり、
S3のバケットポリシーを変更するなり、
単純な構成のリソースを作成していくことが必要になります。
3.テンプレートファイル化にトライしてみる
いろいろな記事を読んで試しましたが、最終的にはユーザーガイド
が一番いい具合に落ち着きました。
もちろん他にもいろいろ勉強しました。
個人的なことですが、udemyを結構信頼している部分もあるのでudemyで最初はyamlファイルの書き方なども勉強しました。
Udemy CloudFormation
4.最終的には試行錯誤
CloudFormationは大まかな構成を作成するまでマネジメントコンソールでエラーを出してくれます。そのエラー文を読んで、ドキュメントを読むと自ずと自分の構成のどこが間違っているのか?と示してくれます。
そしてスタックを実行すると実行途中にエラー理由も吐いてくれます。どの論理IDのところでエラーが吐いているのか教えてくれるので修正箇所の発見も早くなります。
Tips
さて上記の内容はCloudFormationでインフラ構築を実施するための大まかな手順を掲載しました。
ここでは上記の手順をサポートする話を書こうと思います。
(実際にはYamlファイルの書き方などになってきます)
Yamlファイルの構成
僕が個人的に最初に詰まったのがここです。
CloudFormationではいろいろ書いてあるのですが、まず基本的に3つの構成に分かれます。
1. 事前の値
2. 作成する内容
3. 外部スタックからImportするためのExportする内容
この3つになります
サンプルで説明していくと
AWSTemplateFormatVersion: "2010-09-09"
Description:
NAT Gateway Create
# ------------------------------------------------------------#
# NAT Gatewayの作成
# ap-northeast-1aと1cにそれぞれPrivateRouteTableが存在している状態
# そのルートテーブルにEIP付きのNAT Gatewayを構築する
# ------------------------------------------------------------#
Parameters:
PJPrefix:
Description: Enter a prefix of this system.
Type: String
Default: "test"
AllowedPattern: "[a-zA-Z][a-zA-Z0-9][ -~]*"
ConstraintDescription: must begin with a letter and contain only alphanumeric characters.
# ------------------------------------------------------------#
# NAT Gateway AZ:A
# ------------------------------------------------------------#
# NATGatewayA Create
Resources:
NATGatewayA:
Type: "AWS::EC2::NatGateway"
Properties:
AllocationId: !GetAtt NATGatewayAEIP.AllocationId
SubnetId:
Fn::ImportValue:
!Sub "${PJPrefix}-public-subnet-a"
Tags:
- Key: Name
Value: !Sub ${PJPrefix}-natgw-a
# NATGateway For EIP Create
NATGatewayAEIP:
Type: "AWS::EC2::EIP"
Properties:
Domain: vpc
# PrivateRouteA Create
PrivateRouteA:
Type: "AWS::EC2::Route"
Properties:
RouteTableId:
Fn::ImportValue:
!Sub "${PJPrefix}-private-route-a"
DestinationCidrBlock: "0.0.0.0/0"
NatGatewayId: !Ref NATGatewayA
# ------------------------------------------------------------#
# NAT Gateway AZ:C
# ------------------------------------------------------------#
# NATGatewayC Create
NATGatewayC:
Type: "AWS::EC2::NatGateway"
Properties:
AllocationId: !GetAtt NATGatewayCEIP.AllocationId
SubnetId: !Ref PublicSubnetC
Tags:
- Key: Name
Value: !Sub ${PJPrefix}-natgw-c
# NATGateway For EIP Create
NATGatewayCEIP:
Type: "AWS::EC2::EIP"
Properties:
Domain: vpc
# PrivateRouteC Create
PrivateRouteC:
Type: "AWS::EC2::Route"
Properties:
RouteTableId:
Fn::ImportValue:
!Sub "${PJPrefix}-private-route-c"
DestinationCidrBlock: "0.0.0.0/0"
NatGatewayId: !Ref NATGatewayC
# ------------------------------------------------------------#
# Output Parameters
# ------------------------------------------------------------#
Outputs:
# NATGateway EIP
NATGatewayAEIP:
Value: !Ref NATGatewayAEIP
Export:
Name: !Sub "${PJPrefix}-natgw-a-eip"
NATGatewayCEIP:
Value: !Ref NATGatewayCEIP
Export:
Name: !Sub "${PJPrefix}-natgw-c-eip"
Yamlファイルでインデントが使われているのが見えると思いますが、この「インデント」が非常に重要になります。
このインデント次第でスタックが生成されないことが何十件とありました。
一番左にきているのが
1. Parameters
2. Resources
3. Outputs
の3つになります。
この3つの中で絶対に必要なのが
「Resources」
です。
これがないと何も作られません。
その次に
「Parameters」
です。
このパラメータ例えば今回は「PJPrefix」としています。
個人的にはプロジェクト名などに統一することでそのプロジェクトで横展開されていくものだなと思っています
(この部分自分で書いていてもうまく纏まっていないことはわかるのでぼんやりでいいです。)
そして最後に
「Outputs」
です。
これはCloudFormationで作成した値を他のスタックで使いたい時
例えばSubnetのIDとか。
SecurityGroupのIDもそうです。
今回ですと
事前にRouteTableを作成していてそれをOutputしていたので
この中でRouteTableIdを呼び出したかった
みたいな感じです。
RouteTableId:
Fn::ImportValue:
!Sub "${PJPrefix}-private-route-c"
今回ResourcesとかParametersとかOutputsとかいろいろ言いましたが
基本的には
「事前の値」
「作成物」
「出力値」
この3つで構成されることを覚えておけばあとはドキュメントをみても大丈夫です。
ということがこのドキュメントに書かれています
ドキュメント
Fn::ImportValueの使い方
特にAWSの構成がたくさん増えてくると厄介になるのが一つにまとめるとYAMLファイルの構成が長くなりカスタマイズが困難になることです。
(個人的には長いコードはあんまり好きじゃないです。ただファイル数が増えても管理が面倒なので個人的に落ち着くファイル数とコードの長さに設定しています。)
基本的には
RouteTableId:
Fn::ImportValue:
!Sub "${PJPrefix}-private-route-c"
Fn::ImportValue:と書いて
その下の行にインデントを実施して呼び出したい値を持ってくるとなっています。
ただちょっといいなと思った使い方がこちら
ドキュメント
マッピングで Fn::Subのところです
次の例では、${Domain} 変数を Ref 関数の結果の値と置き換えるためにマッピングを使用します。
Name: !Sub
- www.${Domain}
- { Domain: !Ref RootDomainName }
これ!RefのところもImportValue使えます
*!Refは同じYamlファイルで作成したResourceの情報のこと
この場合はRootDomainNameというResourceを作成していてそのリソースの情報を再利用する話
実際に私が使った内容としてはEC2にS3のバケットの読み取りが可能になるためのIAMロールを作成する時に役にたちました
S3AccessPolicies:
Type: AWS::IAM::ManagedPolicy
Properties:
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- s3:ListAllMyBuckets
- s3:AbortMultipartUpload
- s3:RestoreObject
- s3:GetBucketNotification
- S3:GetBucketPolicy
Resource: arn:aws:s3:::*
- Effect: Allow
Action:
- s3:ListBucket
- s3:GetBucketLocation
- s3:PutBucketNotification
Resource:
Fn::Sub:
- arn:aws:s3:::${S3BucketName}
- {
S3BucketName: { "Fn::ImportValue": !Sub "${PJPrefix}-s3" }
}
- Effect: Allow
Action:
- s3:PutObject
- s3:GetObject
Resource:
Fn::Sub:
- arn:aws:s3:::${S3BucketName}/*
- {
S3BucketName: { "Fn::ImportValue": !Sub "${PJPrefix}-s3" }
}
検索の仕方
基本的に今現在は
「AWS::IAM::ManagedPolicy」
という感じで
検索しています。
最初は構成内容から検索していたのですが、最終的にはドキュメントを読んだ方が早いことに気がつきました。
ただAWSのサービスがたくさんあるのでその中から探すのが大変だと思います。
その時は
「サービス名 CloudFormation」
と検索することをお勧めします。
以上です。
豊かな開発ライフを!!
Author And Source
この問題について(CloudFormationを勉強したので聞いて欲しい), 我々は、より多くの情報をここで見つけました https://qiita.com/kazumasamatsumo/items/7013cd312bd5c0967fe1著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .