CloudFormationのGetAZsでエラーが止まらない

お久しぶりです。
QBオンライン担当のSです。

みなさんAWSを利用していますか?
インフラ構築はどうされてますか?CloudFormation使ってますか?

AWSではインフラ構築もコードで行うことを推奨しており、そうすることで手順書などがなくても開発・ステージング・本番環境とパラメーターを変えるだけで気軽に作成できたりしますし、新しいシステムを構築する際にも流用できて大変便利ですよね。

弊社でも利用はされているようですが、少なくとも現在のQBオンラインでは利用しておらず、今回の切り替えはいいタイミングになるということで作成してみました。


・・・で、ハマりました。

みなさんも体験されているかとは思いますが、
大体新しいことをやろうとするとハマるのがこの界隈の宿命ですね!
萌えて燃えてくるってものです!

ちなみにハマった理由は、タイトルにも記載してあるとおりです。
以下、ちょっと踏み込んで書いてみます。

今回のテンプレートはyamlで作成していました。
yamlいいですよね。jsonは許せません。

構成としては以下を実現するものを作成。

  • VPC内に3つのAvailability Zoneを設定する。
  • それぞれのAvailability Zoneに1つのパブリックサブネットと1つのプライベートサブネットをプロビジョニングする。(合計3つずつ)
  • ネットワークACLを作成してそれぞれのサブネットに紐付ける。
  • プライベートサブネットには独立したルートテーブルをそれぞれ作成して設定する。
  • パブリックサブネットは1つのインターネットゲートウェイを設定した共通のルートテーブルを設定する。
  • 高可用性のためにそれぞれのパブリックサブネットにNATGatewayを作成する。
  • プライベートサブネットがS3と安全に接続するためにVPCエンドポイントを作成する。

ちょっと長いですが、ベストプラクティスに則った一般的な構成です。
忘れがちですが、VPC内では3つのAvailability Zoneを利用するようにしましょう!
先日のZone障害は記憶に新しいですが、AWSも3つのZoneを利用する前提です。

というわけでテンプレートをもとにスタック作成!Go!


エラー!Zoneが取得できません!

Template error: Fn::Select cannot select nonexistent value at index 2

なんでや・・・

ハマっているのはここだということは突き止めました。
※全体で650行ほどになったので一部抜粋。

PublicSubnet3:
    Type: 'AWS::EC2::Subnet'
    Properties: 
      AvailabilityZone: !Select [2, !GetAZs '']
      CidrBlock: !Sub '10.${ClassB}.64.0/20'       
      MapPublicIpOnLaunch: true
      VpcId: !Ref VPC
      Tags:
      - Key: Name
        Value: !Join
                 - '_'
                 - - !Sub '10.${ClassB}.0.0/16'
                   - !Select [2, !GetAZs '']
                   - 'Public'
      - Key: Reach
        Value: public

どうもAvailabilityZone: !Select [2, !GetAZs '']が取得できていないようですね・・・

東京リージョンは1a, 1c, 1dだからインデックスが違うのか・・・?
いや、物理IDで取得するはずなので、1cだからとかは関係ないはず・・・

試しにオレゴンとバージニアで作成してみました。


せ、成功している・・・

こういうときは原点に帰って公式ドキュメントですよね。
穴が空くほど読んでも、絶対に公式は正しいはずです。
どれどれ、読んでみますか・・・

EC2-VPC プラットフォームでは、Fn::GetAZs 関数はデフォルトのサブネットがあるアベイラビリティーゾーンのみを返します。デフォルトのサブネットがあるアベイラビリティーゾーンがない場合は、すべてのアベイラビリティーゾーンを返します。

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-getavailabilityzones.html

なるほど、つまりデフォルトサブネットが東京リージョンの3つのZoneにそれぞれ存在するかを見ればいいわけですね!

これだーーーー!!!!!!

見事に1aと1cしかNEEEEEEEEEEEEEEEEEE

どうやら1dは最近できたZoneなので、昔に作成したアカウントだとデフォルトサブネットとしてデフォルトVPCに作成されていないようです。

そんなの気付かないよと言いたい気持ちは分かります。
でも公式に書いてあるんですよね。
穴が空くほど読むのではなく、穴を空けてから不満を言うようにしないといけません(悟り

じゃあZoneを追加してみたらエラーにならないんだろうか・・・
追加するコマンドは以下です。
※今回は1dが無かったため1dを追加しています。

$ aws ec2 create-default-subnet --availability-zone ap-northeast-1d

よし!もう一度スタック作成だ!

CREATE_COMPLETE

まとめ

CloudFormationはハマることも多いですが、作っておいて間違いはありませんし、苦労が実った瞬間こそエンジニアの醍醐味ではないでしょうか。
調子に乗って全部テンプレート作成していますが、毎回ハマっても楽しいですよ!みなさんもいんふらすとらくちゃあずこーどへDive!

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

Bitnami