こんにちは、SREグループの水戸 (@y_310) です。前回の記事でも触れたとおりMoTにはたくさんのサービスが稼働しており、それに応じて様々なインフラリソースも作成されています。そのためリソースの見通しを良くし、インフラ構築時に迷わず命名できるようにするために色々な命名規則を定めています。
命名規則はその組織が置かれている状況や直面している課題によって何を優先するかも異なり絶対的に正しい方法は無いと考えているため、この記事を読んだ方がご自分の状況と照らし合わせて取捨選択の判断がしやすいようにそれぞれの命名規則を決めた理由と合わせて紹介していきます。
サービス名
MoTではサービス名に 世界の一単語の都市名 (市町村名)をつけることをルールとしています。これはいわゆるコードネームですが、このサービス名をベースに後述の関連するリソース名も設定することになります。
以下が具体例です。
- OKの例
- London、Paris、Berlinなど
- Tomari (泊村、街のサイズは考慮しない)
- NGの例
- taxi_dispatcher (説明的、都市名じゃない)
- Kanto (地方の名前)
- Kioicho (都市の中のエリアの名前)
- Shibuya (区も都市の中のエリア)
- Asia (エリア名)
- Ehime (県名)
- Rio_de_janeiro、San_francisco (複数単語)
またこれらのルール以外にガイドラインとして、以下のようなものがあります。
- 発音しやすい
- 長すぎない
- スペルミスしづらい
- 日常会話で混同しづらい (日本の地名は会話に出やすいので主要都市は避けるのが好ましい)
命名規則の採用理由
サービス名として一般的にはそのサービスの機能や役割を示す名前をつけることが多いかと思います (前述の例におけるtaxi_dispatcherなど)が以下の理由によりあえてその選択を避けています。
- サービスの開発開始時にそのサービスにとって最も適切な名前を選択することは難しいことが多い
- サービスの成長に伴い役割が変化し実態と名前が乖離する可能性がある
- AWSリソースなどには設定可能な文字数が短いものもあるが、説明的な名前は長くなりがちで制限に引っかかることがある
- 同じ業務領域に関わるシステムは同じような単語が使われる傾向が強く(MoTであればtaxi、vehicle、geoなど)名前の一意性が低いため検索効率が悪い
また、一単語の都市名 (市町村名)を選択している理由は以下です。
- 都市名である理由
- 短い単語でユニーク性の高い名称が多い
- 十分な数がある
- 厳密に都市名以外の地名を許容していない点については一貫性を持たせたいというこだわり以上の理由はない
- 一単語である理由
- 長さを短く抑えられる
- 複数単語の場合使用箇所によって区切り文字をスペース、アンダースコア、ハイフンなど選択する必要が出て表記揺れが発生しやすいため
- San Francisco、san_francisco、san-francisco、SanFranciscoなど
なおこのルールを導入する場合、名前からは役割を一切推測できないため、社内では全サービスの名前と概要を記載した一覧表を作成しています。
AWSリソース名
AWS上に作成するリソースはまず基本原則として全て小文字でkebab-caseで命名することとしています。これは主にS3の命名規則に従うためです。
具体的なリソース名には以下の命名規則を設定しています。
resource-service[-descriptors]-environment-number[-az-number] resource: リソースの種類 service: サービス名 descriptors: 任意の数のサービスを説明する名前 (同じ種類のAWSリソースを用途に応じて複数作る場合等に使用) environment: 環境(development|staging|productionなど) number: 3桁の連番 (移行等で同名のリソースを複数作る必要が出た時のため) az-number: 1桁のAZの連番 (サブネットのようにAZ毎に同じものを複数作る場合)
リソース種類名の例 | リソース種類の表記 | AWSサービス名 | | ---- | ---- | | role | IAMロール | | ec2 | EC2 | | sqs | SQS | | rds | RDSインスタンス | | eip | Elastic IP | | rdsclstr | RDSクラスタ | | vpc | VPC | | policy | IAMポリシー |
実際に規則を適用した例としては以下のようになります。
# シンプルなケース policy-london-development-001 policy-london-production-001 # 同じ種類のリソース(SQS)を複数作成するケース (*-priorityがdescriptors) sqs-london-high-priority-production-001 sqs-london-low-priority-production-001 # DBマイグレーションのために同名で複数のインスタンスを作るケース rdsclstr-london-staging-001 rdsclstr-london-staging-002 # 複数のAZに同名のサブネットを作るケース subnet-london-development-001-0 subnet-london-development-001-1
命名規則の採用理由
名前を構成する各コンポーネントの目的については規則内で既に説明をつけたためここではその順序について説明します。ただしそもそものところになりますが、名前の一意性を保つのに十分な要素が含まれている事が重要なので、順序については相対的に重要度が下がる問題にはなります。
まず全体として名前はそのリソースの固有性をより表現できる部分から先につけるようにしています。
先頭にリソース種別(rds, sqsなど)を付けているのはIAMポリシー内やアプリケーションの設定内など他の場所からそのリソースを参照する際にそれが何であるのかを分かりやすくする目的があります。
- 多くの場合AWSリソースの設定時は1つのマイクロサービスに関連するリソースしか考慮しない
- Terraformによる構築時などはマイクロサービス単位でまとめて構築するため
- 1つのマイクロサービスにスコープを絞った場合リソース種別だけで対象を一意に特定できることが多い
londonというサービスに対してpolicy、sqs、rdsclstrという部分だけでほぼ目的のリソースであることがわかる
次にサービス名とdescriptors(london, london-high-priorityなど)を付けています。AWSマネジメントコンソール上などリソースが大量に並ぶ画面でも先頭のリソース種別とサービス名の組み合わせで目的のリソースをほぼ一意に特定できるためサービス名をこの順序にしています。また同じサービスのリソースが連続して並ぶので見やすいという観点もあります。
次の環境(development, productionなど)は、オペミスの観点では重要度の高い情報で、先頭につける方式もあり迷うところではあったのですが、基本的にリソースは全てTerraformでコード管理していて環境見間違いによる誤操作のリスクがあまり高くないことや、リソース種別を先頭に置くことのわかりやすさを優先したかったことからこの順序にしています。またAWSアカウントごと分けている環境では不要という考え方もできますが、現実には既存環境で分けられなかったり、アカウント横断してリソース名をスプレッドシートに列挙したりなどアカウント横断でも一意性がある方が扱いやすいこともあるのでアカウント管理方法に関わらず付けたほうが良いと考えています。
残りの番号(001, 001-0など)についてはそもそも先頭に置けないことや重要度が低いことから末尾に配置しています。
AWSアカウント名
アカウント名については様々な用途で作成されることから現状複雑なルールは設定していません。
アカウント名の命名規則は以下です。
mot-[任意の名前]-aws
命名規則の採用理由
先頭のmotは冗長ではあるのですが、将来的に会社が成長し別組織のアカウントを管理するような事が発生した場合に備えて組織の区別ができるように含めています。
末尾のawsも同じく一見冗長なのですが、MoTではGCPのプロジェクトも大量にあり、時折AWSアカウントと同名でGCPにもプロジェクトを作成したいケースがあるため、区別しやすいようにクラウドサービス名を含めています。
おわりに
最後に命名規則を定める目的を整理したいと思います。
- 一貫したルールがあることで本質的な差異だけに着目することができ認知負荷が下がる
- 自動化処理を実装しやすくなる
- 構築時に意思決定が必要な項目が減るため作業が効率化される
- 設定ミスに気づきやすくなる
チームの認識を合わせ一定のルールを決めることは簡単なことではありませんが、決めて運用して得られるメリットはそれより遥かに大きいと感じています。この記事で書いた命名規則はあくまで一例でチームの置かれている状況によって最適解は変わると思いますが、この記事の内容がルールを定める上での議論の叩き台になれば幸いです。