AWS CloudFormation (CFn) でアベイラビリティーゾーン (AZ) を指定する擬似パラメータ参照の書き方を整理してみた

AWS CloudFormation (CFn) でアベイラビリティーゾーン (AZ) を指定する書き方が毎回わからなくなるので、ブログにまとめてみました。擬似パラメータとCFnの組み込み関数を複数組み合わせた書き方になっています。
2024.01.25

AWS CloudFormation (CFn) でアベイラビリティーゾーン (AZ)を指定する書き方が毎回わからなくなる

おのやんです。

みなさん、AWS CloudFormation(以下、CFn) でアベイラビリティーゾーン (以下、AZ) を正しく指定したくないですか?私は指定したいと思っています。

CFnのテンプレートを記述する際には、Visual Studio Code (以下、VSCode)の拡張機能であるcfn-lintを使って構文チェックを行っています。私がよくやってしまうのが、AZをハードコーディングに対する警告です。例を挙げると、Amazon Relational Database Service (以下、RDS) のRDSインスタンスのテンプレート作成時に、この警告にぶつかりました。

この警告を回避・解消する書き方の1つに、擬似パラメータ参照CFn組み込み関数を組み合わせたものがあります。この書き方を採用する場合、CFnによって事前定義されたAZのパラメータや、各関数の文法を把握しておく必要があります。

しかし、この事前定義されたパラメータの書き方が毎回わからなくなります。ということで、今回はAZを記述するための擬似パラメータ参照を改めて整理したいと思います。

警告が出る記法

まず、警告の出る書き方を整理しておきましょう。こちらが、cfn-lintで警告の出るAZの書き方です。

RDSInstance:
  Type: AWS::RDS::DBInstance
  Properties:
    Engine: aurora-postgresql
    EngineVersion: 15.4
    DBClusterIdentifier: rds-cluster-identifier
    AvailabilityZone: ap-northeast-1a # <= Warning!

警告の内容は以下の通りです。

[cfn-lint] W3010: Don't hardcode ap-northeast-1a for AvailabilityZones

こちらの警告は、CFnテンプレートの値にAZの名前をハードコーディングしていることが原因です。

正しい記法

上記の警告を解消する方法のひとつに、以下の書き方があります。

Resources:
  RDSInstance:
    Type: AWS::RDS::DBInstance
    Properties:
      Engine: aurora-postgresql
      EngineVersion: 15.4
      DBClusterIdentifier: rds-cluster-identifier
      AvailabilityZone: !Select         #
        - 0                             # <= Correct!
        - Fn::GetAZs: !Ref AWS::Region  #

!Ref AWS::Regionの部分はCFnの擬似パラメータ参照です。このパラメータにはAWSのリージョンの情報が含まれます。仮に東京リージョンにCFnテンプレートをデプロイした場合は、AWS::Regionの擬似パラメータはap-northeast1の値を返します。

!Ref AWS::Region # => ap-northeast1

こうして得られたリージョン情報に対してFn::GetAZsの組み込み関数を使用することで、AZを取得します。仮に東京リージョンに対してFn::GetAZsを使用した場合は、東京リージョン内のAZがアルファベット順に並んでいる配列を返します。

Fn::GetAZs: !Ref AWS::Region # => [ "ap-northeast-1a", "ap-northeast-1c", "ap-northeast-1d" ]

この配列に対して、Fn::Selectの組み込み関数を使用することで、特定のAZを指定します。ap-northeast-1aのAZを指定する場合は、こちらのAZとインデックス(何番目に並んでいるか)の関係をもとに、0番目の要素をFn::Select関数で指定します

インデックス AZ
0 ap-northeast-1a
1 ap-northeast-1c
2 ap-northeast-1d

AvailabilityZone: !Select         #
  - 0                             # => ap-northeast-1a
  - Fn::GetAZs: !Ref AWS::Region  #

色々なパラメータ・関数が組み合わさることでAZを記述できる

ネットで検索して上記の書き方が出てきたとき、「どんな記法になっているんだ?」と戸惑う場合もあるかと思います(私がそうでした)。

こちらを参考に、Don't hardcode ap-northeast-1a for AvailabilityZones警告をスマートに回避していただければと思います。では!