- 経緯・あらすじ
- 作ったcFnテンプレについて
- インポート検証環境つくり
- 私物AWSでインポート練習してみたら問題が何個も発生した
- リソースが無い時だけRouteとかのリソースを作る編 2021/08/24 0:03 32min
- その方針でやった結果
- 結局インポートする時にやったこと
- できたcFnのテンプレート (197行)
- 感想
- 時間管理
経緯・あらすじ
- 前回までで、業務のAWS(踏み台サーバ周りのNW)を cFnのテンプレにした
- その後、チームメンバーに説明してレビューしてもらった
- それを適用すべく、まず私物AWSに同じ構成+ nginx EC2 を立てて、インポート練習をした
- すると、作ったテンプレでは通らなかったので、足りないところを足していく
- 結果、最終的に、私物AWSを cFn管理にすることができた。
作ったcFnテンプレについて
- 詳しくは 前回の 「15日め」に書きましたが、 CloudFormationの実践ベストプラクティス - Qiita のベストプラクティス構成を踏襲しています。
- 思いっきり「CDKを使いましょう」と書かれてますが、一旦 cFnをマスターしたかったので、このSSHサーバ周りのNWだけ、cFnだけでやってみています
- それをしてよかったか, 悪かったかは 後日 CDKを学んだ時にこのブログに記します。
インポート検証環境つくり
方針
- 本稼働環境を稼働させたままcFn管理にできると思うけれど、それを実証したい
- ので、nginxをec2で動かして、ブラウザで1秒毎にアクセスしてやってみた
- インターネット経由のアクセスだし、(あまり頻繁にしてブロックされると嫌なので)1秒毎で良いと思う(アドオン利用)
やったこと
- 作ったcFnをテンプレをみながら私物AWSでぽちぽちしてつくった
- EC2のnginx部分は↓でやった
私物AWSでインポート練習してみたら問題が何個も発生した
- 練習したら、問題が何個も見つかった
問題1: ネストしたテンプレでは、実際にインポートしたいリソースをインポートできない
- 一番上の stacks/master.yml を「既存のリソースを使用する」で読み込んでも、その .yml で読み込んでる、 cFnのNetwork Stack の Stack IDを入力する画面にしかならなかった
- インポート機能自体が 2019/11 にできたものなので、ネスト先で使ってるリソースのインポートにはまだ対応して無くても仕方ないなと諦めた (2021/08/23)
- インポートが登場した時のクラスメソッドさんの記事: CloudFormationがリソースのインポートに対応しました! | DevelopersIO
- 仕方ないので、 templatex/VPN.yml とかで1つずつ インポートして、それらを読み込む stacks/network/master.yml や stacks/master.yml もインポート作成操作をしようと考えた
- CDKでこのあたり(インポート周り)も楽になるか要チェックポイント
問題2: 個別にインポートしてると Outputs を吐けない
- templates/network/VPC.yml を使ってインポートしようとしたら↓を言われた
- As part of the import operation, you cannot modify or add [Outputs]
- 一旦消して先に進めた
- でもインポートじゃない時だけ Outputs する、でいい気もする (この後やってみたい)
- 多分 UPDATEの時( UPDATE_COMPLETE にする時) には必要そう
- でもインポートじゃない時だけ Outputs する、でいい気もする (この後やってみたい)
問題3: インポートできないリソースがある
- AWS::EC2::Route や AWS::EC2::VPCGatewayAttachment は、インポートに非対応、と実行して初めてわかった
- 一旦、対応してないリソースは消して、(練習用私物AWSで)インポートしてみた
- だが、後にそういう対処は誤りだと思った (既にある場合はリソースを作成しない、にテンプレをConditionalにするのがよさそう、と思っている 2021/08/23 23:35)
(自分の過ち: インポートするcFn Stackにも DeletionPolicy と UpdateReplacePolicy が必要)
- The following resources to import [PubSubAPne1d, VPC, IGW, RouteTableToIGW] must have DeletionPolicy attribute specified in the template.
- cfn-lint でも怒られてたっぽい
問題4: IMPORT_COMPLETE のステータスのスタックを親スタックはインポートできない (のでUPDATE_COMPLETEにしておく必要がある)
- 4つを一旦インポートしてみたので、その4つをインポートして stacks/network/master.yml を作ろうと思った。
- しかし、 ↓のように言われた
Stack arn:aws:cloudformation:ap-northeast-1:1728XXXXXXXX:stack/igw-20210821/ed4a66a0-0253-11ec-b20d-XXXXXXXX5d45 is not in an importable status, current stack status is IMPORT_COMPLETE.
- IMPORT_COMPLETE では importable ではないらしい
- ダメといわれた stack で、 変更セットを作成して、適用すると、 UPDATE_COMPLETE になった。そうすると、 stacks/network/master.yml でインポートしたところ、そのエラーは言われなくなった。
問題5: 0.0.0.0/0 のRoute が既にあるから追加できない と言われる
- PubSubを一度、Route 抜きで既存リソースをインポートして作ったあとに、 Routeありにテンプレを戻して更新セット作ろうとしたら、「0.0.0.0/0 のルートはあるから」作れないよ、と言われた
- ので、 テンプレをConditionalにしてやり直そうと考えているところである 2021/08/23 23:42
リソースが無い時だけRouteとかのリソースを作る編 2021/08/24 0:03 32min
- あまり役立たなかった AWSドキュメント
- 少し役立った AWSドキュメント
- ☆ドンピシャなAWSドキュメント
- なんか、 渡したParameterでの分岐しかできないようだった
- 既にリソースがあるかをcFnに調べてもらって分岐はできなさそうだった
- まだcFnは発展途上だから仕方ないかな
- CDKでできるかは要チェックポイント
- 途中で出てきた noecho のマスク助かる (パスワードとかを非表示にできる)
- 「テンプレートに認証情報を埋め込まない」
aws::novalue擬似パラメーターは、戻り値として使用された場合、対応するリソースプロパティを削除します。
- cFnでソフトウェアインストールとかする時は、cFnのヘルパースクリプトというのを使うらしい
その方針でやった結果
- 概ねうまく行った
- 最終的に、nginxを止めないまま、CloudFormation管理下に置くことに成功した
問題6: 子を持つCloudFormation stackはインポートできない
- 一番上のmaster.yml は無くして、networkスタックとかを5つ管理しようと思った
結局インポートする時にやったこと
↓のテンプレを使ってインポートするには…
- ↓のテンプレの templates/ の各ファイルを使って、4つのスタック(VPC, IGW, PublicSubnetRouteTable, Subnet) をインポート作成していく
- その際、 Outputs と importに対応してないリソース(Conditionalなリソース)の部分は手元で消して、その手元のテンプレをcFnのマネジネントコンソールでアップロードしてインポートしていく (IMPORT_COMPLETEになる)
- インポートしたら、Outputsと 消したリソースを戻した元の状態のテンプレをcFnマネジネントコンソールでアップロードして変更セットをつくり、反映し、 IMPORT_COMPLETE を UPDATE_COMPLETEにしておく
- 4つの templates のリソースをインポートできたら、network スタックを作る
- S3に下のテンプレを全部アップロードして、 cFnマネジネントコンソールで S3上の stacks/network/master.yml を選んでインポートする
- インポートできたら、 変更セットを現在のテンプレートを使用する で作って、反映し、 IMPORT_COMPLETE状態からUPDATE_COMPLETE にしておく
できたcFnのテンプレート (197行)
stacks/network/master.yml (48行)
AWSTemplateFormatVersion: "2010-09-09" Description: MyService Network Stack Resources: VPC: Type: AWS::CloudFormation::Stack DeletionPolicy: Retain UpdateReplacePolicy: Retain Properties: Parameters: VpcCidrBlock: 172.31.0.0/16 TemplateURL: 'https://myservice-cfn.s3.ap-northeast-1.amazonaws.com/templates/network/VPC.yml' IGW: Type: AWS::CloudFormation::Stack DeletionPolicy: Retain UpdateReplacePolicy: Retain Properties: Parameters: VpcId: !GetAtt VPC.Outputs.VpcId CreateOrImport: "import" TemplateURL: 'https://myservice-cfn.s3.ap-northeast-1.amazonaws.com/templates/network/IGW.yml' RouteTableToIGW: Type: AWS::CloudFormation::Stack DeletionPolicy: Retain UpdateReplacePolicy: Retain Properties: Parameters: VpcId: !GetAtt VPC.Outputs.VpcId IgwId: !GetAtt IGW.Outputs.IgwId CreateOrImport: "import" TemplateURL: 'https://myservice-cfn.s3.ap-northeast-1.amazonaws.com/templates/network/PublicSubnetRouteTable.yml' # Subnets PubSubAPne1d: Type: AWS::CloudFormation::Stack DeletionPolicy: Retain UpdateReplacePolicy: Retain Properties: Parameters: VpcId: !GetAtt VPC.Outputs.VpcId VpcCidrBlock: 172.31.32.0/20 AvailabilityZone: "ap-northeast-1d" RouteTableId: !GetAtt RouteTableToIGW.Outputs.RouteTableId InternetAccessibility: "public" CreateOrImport: "import" TemplateURL: 'https://myservice-cfn.s3.ap-northeast-1.amazonaws.com/templates/network/Subnet.yml'
templates/network/
VPC.yml (22行)
AWSTemplateFormatVersion: "2010-09-09" Parameters: VpcCidrBlock: Type: String AllowedPattern: (\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2}) Description: IP address class used for VPC. Resources: VPC: Type: AWS::EC2::VPC DeletionPolicy: Retain UpdateReplacePolicy: Retain Properties: CidrBlock: !Ref VpcCidrBlock Tags: - Key: Name Value: vpc-cfn Outputs: VpcId: Value: !Ref VPC
IGW.yml (34行)
AWSTemplateFormatVersion: "2010-09-09" Parameters: VpcId: Type: String CreateOrImport: Type: String AllowedValues: ["newly create", "import"] Conditions: CreateNewAttachment: !Equals [!Ref CreateOrImport, "newly create"] Resources: IGW: Type: AWS::EC2::InternetGateway DeletionPolicy: Retain UpdateReplacePolicy: Retain Properties: Tags: - Key: Name Value: igw-cfn AttachGateway: Type: AWS::EC2::VPCGatewayAttachment Condition: CreateNewAttachment DeletionPolicy: Retain UpdateReplacePolicy: Retain Properties: VpcId: !Ref VpcId InternetGatewayId: !Ref IGW Outputs: IgwId: Value: !Ref IGW
PublicSubnetRouteTable.yml (41行)
AWSTemplateFormatVersion: "2010-09-09" Parameters: VpcId: Type: String IgwId: Type: String CreateOrImport: Type: String AllowedValues: ["newly create", "import"] Conditions: CreateRoute: !Equals [!Ref CreateOrImport, "newly create"] Resources: RouteTable: Type: AWS::EC2::RouteTable DeletionPolicy: Retain UpdateReplacePolicy: Retain Properties: VpcId: !Ref VpcId Tags: - Key: Name Value: public-subnet-routetable-cfn # Routing # (Route for local will be created automatically as 1st priority routing) # PubSub-Internet Routing RouteToIGW: Type: AWS::EC2::Route Condition: CreateRoute DeletionPolicy: Retain UpdateReplacePolicy: Retain Properties: RouteTableId: !Ref RouteTable DestinationCidrBlock: 0.0.0.0/0 GatewayId: !Ref IgwId Outputs: RouteTableId: Value: !Ref RouteTable
Subnet.yml (52行)
AWSTemplateFormatVersion: "2010-09-09" Parameters: VpcId: Type: String VpcCidrBlock: Type: String AllowedPattern: (\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2}) AvailabilityZone: Type: String AllowedValues: - "ap-northeast-1a" - "ap-northeast-1c" - "ap-northeast-1d" RouteTableId: Type: String InternetAccessibility: # This Parameter is used only in Name tag Type: String AllowedValues: - "public" - "private" CreateOrImport: Type: String AllowedValues: ["newly create", "import"] Conditions: CreateRouteTableAssociation: !Equals [!Ref CreateOrImport, "newly create"] Resources: Subnet: Type: AWS::EC2::Subnet DeletionPolicy: Retain UpdateReplacePolicy: Retain Properties: AvailabilityZone: !Ref AvailabilityZone VpcId: !Ref VpcId CidrBlock: !Ref VpcCidrBlock Tags: - Key: Name Value: !Join ["-", [!Ref InternetAccessibility, "subnet", !Ref AvailabilityZone, "cfn"]] # Associate Route Table To Subnet AssoRouteTable: Type: AWS::EC2::SubnetRouteTableAssociation Condition: CreateRouteTableAssociation DeletionPolicy: Retain UpdateReplacePolicy: Retain Properties: SubnetId: !Ref Subnet RouteTableId: !Ref RouteTableId
感想
- 慣れたらスムーズかも
- でも全然ワンタッチではないので、CDKに期待
- メキメキとCloudFormation力がついていってるのが分かるのはいいね (AWS NW知識もついた)
- CloudFormation力は CDKでも要るはずなのでいいんじゃないかなと思う
時間管理
- 前回まで(0からcFnを学んで、cFnテンプレにして、チームメンバーに共有するまで)で 23.5時間かかっていたらしい
- ~ 2021/7/28
- 今回は、そのテンプレを使って私物AWSでcFn管理下にするまでで、9時間かかった