【AWS Coudformation】カスタム名のプラクティス

# 概要

Cloudformationにはカスタム名を指定可能なリソースが存在しますが、仕様上カスタム名を指定したリソースを置換更新しようとするとエラーになります。
エラーになるケース、コンソールで分かりやすく表示させる代替手段を記載します。

# Cloudformationリソースのカスタム名

## Nameタイプ
Cloudformationリソースには、一意の物理IDが自動付与されますが、この物理IDを手動で指定可能なNameタイプフィールドがあります。

[Nameタイプ](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-name.html)

Nameタイプのフィールド名はリソースによって異なります。
例えば、AWS::EC2::SecurityGroup であれば、"GroupName"が、該当します。
また、AWS::AutoScaling::LaunchConfigurationであれば、”LaunchConfigurationName”が該当しますが、これはドキュメントに明記されていません。（2020年3月8日時点）

## カスタム名指定時の制約

リソースにカスタム名が指定されていると、Cloudformationでスタックを更新する際「リソースの置換更新」ができません。
置換更新等の更新動作については以下に記述があります。

[スタックのリソースの更新動作](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html)

どうにか置換更新したい場合は、一度カスタム名を変えて反映して、また元に戻すなど、方法はあるにはあるとは思います。

## カスタム名を指定する動機

思いつく動機は以下です。

- AWSコンソールで見やすくしたい
- スタック外部からカスタム名で参照したい（S3バケット名など）

後者についてはカスタム名を指定するのが良さそうです。
勿論、スタックでバケット名をOutputし、それを参照する方がいいのですが、とはいえサクッとバケット名で参照したいことも多いと思います。

前者について、置換更新時の制約をどの程度受け入れられるかによりますが、「ちょっと変更したいんだけど置換更新になってしまう」というのは良くあると思います。

先日、AutoScaling groupの起動設定のリソースである AWS::AutoScaling::LaunchConfiguration  で InstanceType を変更する際に、これに遭遇しました。


# カスタム名指定時と未指定時の更新の様子

最初の例として、AWS::AutoScaling::LaunchConfiguration を使用します。

## カスタム名を指定した LunchConfigration の更新

以下のテンプレートでスタックを作成します。

スタック名: lunchconfig-named

    AWSTemplateFormatVersion: '2010-09-09'
    Description: Named LaunchConfiguration
    
    Parameters:
      InstanceType:
        Type: String
    
    Resources:
      LaunchConfiguration:
        Type: AWS::AutoScaling::LaunchConfiguration
        Properties: 
          LaunchConfigurationName: my-launch-configration
          ImageId: ami-0af1df87db7b650f4
          InstanceType: !Ref InstanceType

パラメータのInstanceTypeは"t3.nano"で作成


<img width="1033" alt="_2020-03-08_11.34.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103461/18595b14-9159-9651-769a-ecdc13ef2342.png">



作成された起動設定では「名前」に指定したものが表示されていて、非常に見やすいです。

![_2020-03-08_11.26.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103461/96b0286b-2fd2-308a-fe4a-f28b0150317a.png)

InstanceTypeを"t3.nano" → "t3.micro"に変えてスタックを更新しようとしてみます。

<img width="1005" alt="_2020-03-08_11.36.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103461/73c62b83-fc52-a7ba-7275-586af4a31258.png">

カスタム名を指定したリソースの置換更新はできないよと怒られます。

<img width="1059" alt="_2020-03-08_11.37.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103461/5e5576a4-28f6-9a21-ee1a-68a1dffc2365.png">

    CloudFormation cannot update a stack when a custom-named resource requires replacing. 
    Rename my-launch-configration and update the stack again.

AWS::AutoScaling::LaunchConfiguration のドキュメントで、InstanceTypeは置換更新が必要であると記載があるので、この挙動になるということが分かります。

<img width="1094" alt="_2020-03-08_11.38.31.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103461/4026a5a9-bcf7-2db1-fb8c-0480698b855e.png">

せっかく分かりやすい表示なのですが、こういった更新時にエラーとなるのは不便です。

## カスタム名を指定しない LunchConfigration の更新

今度は、以下のテンプレートでスタックを作成します。

LaunchConfigurationName が削除されています。

スタック名: lunchconfig-unnamed

    AWSTemplateFormatVersion: '2010-09-09'
    Description: AutoScaling::LaunchConfiguration
    
    Parameters:
      InstanceType:
        Type: String
    
    Resources:
      LaunchConfiguration:
        Type: AWS::AutoScaling::LaunchConfiguration
        Properties: 
          ImageId: ami-0af1df87db7b650f4
          InstanceType: !Ref InstanceType

作成された起動設定では、自動生成された名前が表示されます。

以下の命名規則となるようです。

リソース論理IDは、上記テンプレートでの "Resources" 直下にある "LaunchConfiguration" を指します。

    <スタック名>-<リソース論理ID>-<ランダム文字列>

![_2020-03-08_11.49.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103461/c1a58ef8-8881-2cae-b3f9-cccb7bec2013.png)

（まあそこまで見づらいというほどでもないかも）

こちらも先ほどと同様に、InstanceTypeを"t3.nano" → "t3.micro"の更新をしようとすると、無事成功します。

## タグ名を指定してコンソール上わかりやすく表示する

コンソール上の表示改善の代替案として、Nameタグを指定する方法があります。

タグを指定可能で、AWSコンソールからタグを表示できるリソースについては、Nameタグ指定を行うことで、指定した名称をコンソールに表示できます。

以下、セキュリティグループのテンプレート例です。

    AWSTemplateFormatVersion: '2010-09-09'
    Description: SecurityGroup
    
    Resources:
      SecurityGroup:
        Type: AWS::EC2::SecurityGroup
        Properties:
          GroupDescription: my security group
          Tags: 
          - Key: Name
            Value: my-security-group

AWS::EC2::SecurityGroupのカスタム名はGroupNameですが、これを指定せず、Tagsに Name: <表示したい名称> を指定します。

[](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group.html)

Name欄に指定した名称が表示されます。

この対応は、コンソールでタグが表示できるものについてのみ可能です。

![_2020-03-08_13.25.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103461/8d06a168-5f64-2fb9-e829-25204ec6086c.png)

Nameタグが表示されていない場合は、右上の歯車アイコンから、列の表示を設定してください。

![_2020-03-08_13.27.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103461/1146e625-4506-9836-1a84-5949bee2e0a8.png)

# まとめ

カスタム名を指定したCloudformationリソースが更新時にエラーになるケースと、Nameタグを使用したAWSコンソールで見やすい表示名設定の代替案を記載しました。

作成済みスタックの置換更新時エラーは、忘れた頃に遭遇することも多いので、初期構築時にこの辺の挙動の意識しておいた方が良さそうです。