🏷️

独断と偏見でAWSリソースの物理名を決める

2023/01/17に公開

はじめに

AWSの環境構築をする際に最も悩むことの一つは、AWSリソースの物理名を考えることだと思います。最近はプロジェクトごとや環境ごとにAWSアカウントを分けて運用することも増えてきたと思いますが、場合によっては複数のプロジェクトや環境を一つのAWSアカウントに混ぜて運用することもあるかと思います。その際に命名規則がバラバラだと、リソースの一覧を見たときに何がどのプロジェクトなのか、ぐちゃぐちゃでわからないといったことになったりします。また、最初は一つのプロジェクトしかないことを前提に命名規則を決めてうまく運用していたけど、あとから別のプロジェクトが相乗りしてきたときに、命名規則が崩壊するといったケースもあると思います。
今回はどのようなアカウント設計になったとしても汎用的に使えるAWSリソースの命名規則を勝手に決めてみます。

プロジェクトコードを決めておく

ポイントはプロジェクトごとに短いコードを決めておくことです。ティッカーシンボルのように、なるべく短い文字列がいいです。そして組織内でユニークである必要があります。たとえば「 ありがとうゲーム 」のようなサービス名のプロジェクトだとしたらプロジェクトコードは「 thx 」などにします。2〜5文字くらいまでが短くていいかなと思います。組織内で、プロジェクトコード一覧を管理するといいですね。

コスト配分タグ戦略

命名規則とは直接関係ないですが、AWSの場合はプロジェクトごとや環境ごとにコストを調べようと思ったら、タグ戦略を考える必要があります。コスト配分タグは、 ProjectEnv というタグキーを設定することにして、「開発環境のありがとうゲーム」に関するAWSリソースには全て Project=thx Env=dev というタグをつけます。同じように商用環境には Project=thx Env=prd というタグをつけることにします。このようにタグをつけておけば「ありがとうゲーム全体のコスト」を出したい時は Project=thx でフィルタリングすればいいですし、「商用環境のありがとうゲームのコスト」を出したいときは Project=thx かつ Env=prd でフィルタリングすれば調べることができます。
https://docs.aws.amazon.com/ja_jp/awsaccountbilling/latest/aboutv2/custom-tags.html

話が脱線してしまいましたが、以下に思いつく限りのAWSリソースの名前を挙げてみます。

独断と偏見のAWSリソース物理名リスト

※以降に出てくる例ではプロジェクトコードを thx 、環境名を dev として表示しています。 実際には環境名は stg だったり、 prd だったり作成する環境によって変わります。
※「?」マークは有っても無くてもどちらでも可の意味で使っています。
※なんとなく {プロジェクトコード}-{環境名}-{リソースタイプ}-{追加情報} 的な感じですが、ものによっては例外もある感じです。
※EC2インスタンス名やセキュリティグループ名は厳密にはNameタグだったり、RDSクラスターは名前というよりIDにあたるものですが、リストに含めています。

リソースタイプ リソース名
IGW {プロジェクトコード}-{環境名}-igw
例)thx-dev-igw
VPC {プロジェクトコード}-{環境名}-vpc
例)thx-dev-vpc
サブネット {プロジェクトコード}-{環境名}-subnet-{public|private|isolated}-{AZアルファベット}
例)thx-dev-subnet-public-a ※igwへのルート有
例)thx-dev-subnet-private-c ※natへのルート有
例)thx-dev-subnet-isolated-d ※ローカルルートのみ
ルートテーブル {プロジェクトコード}-{環境名}-rtb-{public|private|isolated}-{AZアルファベット}
例)thx-dev-rtb-public-a ※igwへのルート有
例)thx-dev-rtb-private-c ※natへのルート有
例)thx-dev-rtb-isolated-d ※ローカルルートのみ
NAT {プロジェクトコード}-{環境名}-nat-{AZアルファベット}
例)thx-dev-nat-c
EIP {プロジェクトコード}-{環境名}-eip-{追加情報}
例)thx-dev-eip-nat-c
セキュリティグループ {プロジェクトコード}-{環境名}-sg-{追加情報}
例)thx-dev-sg-backend
EC2インスタンス {プロジェクトコード}-{環境名}-ec2-{追加情報}
例)thx-dev-ec2-step ※踏み台サーバー
EC2キーペア {プロジェクトコード}-{環境名}-ec2-{追加情報}-keypair
例)thx-dev-ec2-step-keypair
ECSクラスター {プロジェクトコード}-{環境名}-cluster
例)thx-dev-cluster
ECSタスク定義 {プロジェクトコード}-{環境名}-{種類}-task
例)thx-dev-web-task
例)thx-dev-admin-task
例)thx-dev-spot-task ※ECSタスクスケジューリング用
ECSサービス {プロジェクトコード}-{環境名}-{種類}-task
例)thx-dev-web-service
例)thx-dev-admin-service
ALB {プロジェクトコード}-{環境名}-alb-{追加情報}
例)thx-dev-alb-web
例)thx-dev-alb-admin
ターゲットグループ {プロジェクトコード}-{環境名}-tg-{追加情報}
例)thx-dev-tg-web-1
例)thx-dev-tg-web-2※BlueGreanデプロイ用に2を用意
※ターゲットグループ名は上限32文字までと制限が厳しいのでたまに引っかかります
RDSクラスター {プロジェクトコード}-{環境名}-{エンジンファミリー+バージョン}-{サーバーレス情報?}-cluster
例)thx-dev-mysql80-slv2-cluster ※slv2はserverless v2の意
例)thx-dev-mysql57-cluster
RDSクラスターインスタンス {プロジェクトコード}-{環境名}-{エンジンファミリー+バージョン}-{サーバーレス情報?}-cluster-instance-{インスタンス番号}
例)thx-dev-mysql80-slv2-cluster-instance-1
DBサブネットグループ {プロジェクトコード}-{環境名}-subnetgrp-rds
例)thx-dev-subnetgrp-rds
redisクラスター {プロジェクトコード}-{環境名}-redis-cluster
例)thx-dev-redis-cluster
ElastiCacheサブネットグループ {プロジェクトコード}-{環境名}-subnetgrp-cache
例)thx-dev-subnetgrp-cache
OpenSearch {プロジェクトコード}-{環境名}-opensearch
例)thx-dev-opensearch
Lambdaファンクション {プロジェクトコード}-{環境名}-{関数名}
例)thx-dev-stopNeptuneCluster
Lambdaレイヤー {プロジェクトコード}-{環境名}-layer-{追加情報}
例)thx-dev-layer-firebase-admin
IAMロール {プロジェクトコード}-{環境名}-role-{プリンシパル}-{追加情報?}
例)thx-dev-role-lambda
IAMポリシー {プロジェクトコード}-{環境名}-policy-{許可概要}
例)thx-dev-policy-s3-access
例)thx-dev-policy-ssm-access
API Gateway {プロジェクトコード}-{環境名}-{APIタイプ}-api
例)thx-dev-rest-api
例)thx-dev-websocket-api
例)thx-dev-http-api
CFnスタック {プロジェクトコード}-{環境名}-{概要}
例)thx-dev-network ※VPC系
例)thx-dev-functions ※Lambdaファンクションたち
例)thx-dev-rest-api ※API Gateway
パラメータストア /{プロジェクトコード}/{環境名}/{キー名}
例)/thx/dev/APP_KEY
Amplifyアプリケーション {プロジェクトコード}-{環境名}-{概要}
例)thx-dev-frontend-admin-web
例)thx-dev-frontend-client-web
例)thx-dev-frontend-admin-flutter
例)thx-dev-frontend-client-flutter

よく使うAWSリソースを挙げてみました。考えてみたらAWSサービスはたくさんあるので全て列挙するのは到底無理でした。初めてのリソースタイプを作ることになったらその都度考えるようにしています。CDKでやる場合は物理名を作成するだけの専用の関数を用意したりしています。

例外

S3のバケット名は、URLの一部として使われるものなので、同一リージョン内でユニークである必要があるため、命名規則を守れるか確定しないので例外としました。
Amplifyのアプリケーション名はAmplify CLIから作成したときは20文字以下にしなければならなかったので制限が厳しすぎるため例外扱いにしていたのですが、AWSコンソールから作成すれば20文字を超えて設定できるようになっていました。Amplify CLIのバージョンによって差異があるかもしれません。

CDKによる物理名の決定

CDKの開発者ガイドには以下のような記載があります。

リソースへの物理名の割り当てには、AWS CloudFormation でいくつかの欠点があります。最も重要なことは、リソースに物理名が割り当てられている場合、作成後に不変であるリソースのプロパティへの変更など、リソースの置き換えが必要なデプロイ済みリソースへの変更は失敗することです。
引用元:https://docs.aws.amazon.com/cdk/v2/guide/resources.html

CDKでAWSリソースを管理している場合、CDKのコードの一部を変更することによって、リソースの置き換え(作り直し)が発生することがあります。置き換え時のデプロイフローは、新たにリソースを作成したあとに、古くなったリソースの削除を行うため、物理名を指定していて変更を行なっていなかった場合、名前が重複してしまい変更は失敗します。物理名を指定していなければ、CDKが自動で物理名を割り当てるため起きない事象なのですが、物理名をCDKに任せるとわけわからない名前になってコンソールから非常に見づらくなるので、私はなるべく指定するようにしています。置き換えが発生することはcdk diffコマンドで事前にわかるため、その場合は仕方がないので名前を変更して対応します。

まとめ

需要があるのかわかりませんが、いままで何度か環境構築をしてきた中で、少しずつこうしたほうがわかりやすかったなと自分なりにアップデートしてきた名前なので、日々変わっていくとは思いますが現状としてはこんな感じです。

レスキューナウテックブログ

Discussion