🦩

【CFn】リソースのプロパティに時折登場する「カスタム名項目」とName Tagとの違いについての理解を深める。

2022/10/24に公開

本記事は、

前々回の記事内で取り扱った、

・CAPABILITY_IAM
及び
・CAPABILITY_NAMED_IAM

の違いについて「カスタム名をつけているかどうか」であるとしていたものの、この”カスタム名”の実態が何であるかいまいちわかっていなかったので、簡単なテストを兼ねてドキュメントから理解を深めていこうと思いました。

終わってみると結構意義のあるテーマだったのでよろしければ是非お付き合いいただけたら幸いです。

早速以下テンプレートを用意しました。

sample.yml

AWSTemplateFormatVersion: "2010-09-09"
Description: Custom Role Test

Resources:
  MySSMMICRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: 'Allow'
            Principal:
              Service:
                - 'ec2.amazonaws.com'
            Action:
              - 'sts:AssumeRole'
      Path: '/'
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
# このRoleNameでつける名前と↓ 
      RoleName: ThisNameWasSetByRoleName
# このNameタグ↓でつける名前はどう違うの?      
      Tags:
        - Key: Name
          Value: ThisNameWasSetByTag

なんの役割をつけているかは今回問題ではないのでスルーください。

コードブロック内のコメントにも記載の通り、タグでつける名前と今回のようなIAM Roleだと「RoleName」という項目(プロパティ)でつける名前の役割の違いに注目します。

早速スタックで↑のRoleを作成

前々回記事でも触れましたが、RoleNameを設定しているので、

カスタム名入りのRoleがリソースに含まれている事を承認するチェックボックスが出現しますが、チェックしてスタックを作成します。

それぞれ作成後にどこに表示されているかまず見てみます。

まずCloudFormationリソース画面を見るに、

・論理ID=MySSMMICRole
・物理ID=ThisNameWasSetByRoleName(RoleName:で設定した名前)

になっています。

IAMのコンソール画面


Nameタグを設定せずに作成した場合

「RoleName:」を設定せずに作成した場合

※自動で名前=物理IDが割り振られました。

当然といえば当然なのですが、RoleNameが無いからと言ってNameタグがそこに繰り上がるような関係性ではありません。

カスタム名は「自動で生成されるわかりにくい名前の代わりに、自分で名前を指定する項目」であるという事がわかりそうです。

公式ドキュメントにも以下のように説明されています。

カスタム名を使用すると<中略>、一見して判別しやすい名前を指定することができます。
名前を指定しない場合、CloudFormation は一意の物理IDを生成してリソースの名前とします。

カスタム名をサポートしているリソース一覧(2022/10/24段階)

今現在31タイプにカスタム名項目が存在します。

以下ドキュメントの構文から対応しているカスタム名項目を拾って()内に記載しました。

Type(カスタム名項目:)

AWS::ApiGateway::ApiKeyl(Name:)
AWS::ApiGateway::Model(Name:)
AWS::CloudWatch::Alarm(AlarmName:)
AWS::DynamoDB::Table(TableName:)
AWS::ElasticBeanstalk::Application(ApplicationName:)
AWS::ElasticBeanstalk::Environment(EnvironmentName:)
AWS::CodeDeploy::Application(ApplicationName:)
AWS::CodeDeploy::DeploymentConfig(DeploymentConfigName:)
AWS::CodeDeploy::DeploymentGroup(DeploymentGroupName)
AWS::Config::ConfigRule(ConfigRuleName:)
AWS::Config::DeliveryChannel(Name:)
AWS::Config::ConfigurationRecorder(Name:)
AWS::ElasticLoadBalancing::LoadBalancer(LoadBalancerName:)
AWS::ElasticLoadBalancingV2::LoadBalancer(Name:)
AWS::ElasticLoadBalancingV2::TargetGroup(Name:)
AWS::EC2::SecurityGroup(GroupName:)
AWS::ElastiCache::CacheCluster(ClusterName:)
AWS::ECR::Repository(RepositoryName:)
AWS::ECS::Cluster(ClusterName:)
AWS::Elasticsearch::Domain(DomainName:)
AWS::Events::Rule(Name:)
AWS::IAM::Group(GroupName:)
AWS::IAM::ManagedPolicy(ManagedPolicyName:)
AWS::IAM::Role(RoleName:)
AWS::IAM::User(UserName:)
AWS::Lambda::Function(FunctionName:)
AWS::RDS::DBInstance(DBName:)
AWS::S3::Bucket(BucketName:)
AWS::SageMaker::NotebookInstance(NotebookInstanceName:)
AWS::SNS::Topic(TopicName:)
AWS::SQS::Queue(QueueName:)

実際には構文内に「●●Name:」である項目が1つの場合もあれば、
Type名と合致するカスタム名項目の他にも存在する場合もありました。

※ 例【AWS::RDS::DBInstance】の場合
DBName: String,
DBParameterGroupName: String,
DBSubnetGroupName: String,
CharacterSetName: String,
DomainIAMRoleName: String,
MasterUsername: String,
NcharCharacterSetName: String,
OptionGroupName: String,

[Type名:カスタム名設定プロパティ]が[1:1]であるのか[1:多]であるかは不明ですが、前章のドキュメントの記載を信じれば、
「名前を指定しない場合、CloudFormation は一意の物理IDを生成」するのがカスタム名と言えるはずなので、設定しなかった場合にエラーが起きたり、空白のまま進むような項目はカスタム名を生成する項目ではないと判断して良いかと考えています。

(毎度の事ですが認識に間違いがあれば是非ご指摘ください。)

カスタム名についての注意点

一意性制約のある項目である事

リソース名は実行中のすべてのスタックおいて一意である必要があります。
テンプレートを再利用して複数のスタックを作成する場合、テンプレートに基づくカスタム名は変更するか削除する必要があります。

ドリフトの対象になる事。

スタックリソースの管理を CloudFormation以外で行うことも避けてください。
例えば、スタックに属しているリソースの名前をCloudFormationを使用せずに変更した場合、その>スタックを更新または削除しようとしたときにエラーが発生します

今度はタグについて考えてみます。

公式ドキュメントからカテゴリのタグ付けを見ると、

技術タグ
名前 — 個々のリソースを識別する

Nameタグは”Technical Tags”にカテゴライズされるようです。

ここでいう”識別をする”のが我々ユーザーである場合もあれば、タグ毎にコストを視覚化するなど、非ユーザーが主語になる事もあるかと思います。

一方リソースの物理IDはというと、識別出来る文字列が入る場合もありますが、「人間が覚えきる」事を目的として生成されていないように思います。

私はドメインに関してはまだまだ浅学ですが、
このあたりはIPとDomainの関係(数字の羅列だと記憶しにくいIPに意味のある文字列をマッピングする行為)に近いのではないかと思いました。

EC2のような特に必要がなければ「たったひとつ」である認識を持つ必要も「名前をつけて愛でる」必要もないものと、確実にそれが「それ」である事を意識すべきものの違いでもあるかなと思いました。

そうした考察を念頭に先ほどの一覧やカスタム名項目を見返すとよりAWSの考えや、プロパティの意図する所がより腑に落ちるようになったように思います。

以上でした。

お読みいただきありがとうございました^^

寒くなってきましたので、暖かくしてお過ごしください☆

Discussion