独断と偏見でAWSリソースの物理名を決める
はじめに
AWSの環境構築をする際に最も悩むことの一つは、AWSリソースの物理名を考えることだと思います。最近はプロジェクトごとや環境ごとにAWSアカウントを分けて運用することも増えてきたと思いますが、場合によっては複数のプロジェクトや環境を一つのAWSアカウントに混ぜて運用することもあるかと思います。その際に命名規則がバラバラだと、リソースの一覧を見たときに何がどのプロジェクトなのか、ぐちゃぐちゃでわからないといったことになったりします。また、最初は一つのプロジェクトしかないことを前提に命名規則を決めてうまく運用していたけど、あとから別のプロジェクトが相乗りしてきたときに、命名規則が崩壊するといったケースもあると思います。
今回はどのようなアカウント設計になったとしても汎用的に使えるAWSリソースの命名規則を勝手に決めてみます。
プロジェクトコードを決めておく
ポイントはプロジェクトごとに短いコードを決めておくことです。ティッカーシンボルのように、なるべく短い文字列がいいです。そして組織内でユニークである必要があります。たとえば「 ありがとうゲーム
」のようなサービス名のプロジェクトだとしたらプロジェクトコードは「 thx
」などにします。2〜5文字くらいまでが短くていいかなと思います。組織内で、プロジェクトコード一覧を管理するといいですね。
コスト配分タグ戦略
命名規則とは直接関係ないですが、AWSの場合はプロジェクトごとや環境ごとにコストを調べようと思ったら、タグ戦略を考える必要があります。コスト配分タグは、 Project
と Env
というタグキーを設定することにして、「開発環境のありがとうゲーム」に関するAWSリソースには全て Project=thx
Env=dev
というタグをつけます。同じように商用環境には Project=thx
Env=prd
というタグをつけることにします。このようにタグをつけておけば「ありがとうゲーム全体のコスト」を出したい時は Project=thx
でフィルタリングすればいいですし、「商用環境のありがとうゲームのコスト」を出したいときは Project=thx
かつ Env=prd
でフィルタリングすれば調べることができます。
話が脱線してしまいましたが、以下に思いつく限りの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