クラウド利用におけるネーミングルールの問題

# はじめに

プログラミングにおいて、開発ルールはいつも悩ましい問題です。

例えば、文化の違う2つの開発チームで新規アプリケーション開発の別の箇所を並行開発する場合などに、コーディングルールやメソッドの使い方の相違からシステム全体として不統一な設計がなされる可能性があります。

これは、プログラミングにおけるパラダイムの問題だけでなく、**変数の命名**だけを取っても生じる可能性があります。

**同様に、クラウドリソースのネーミングをチームで統一しておくことは、後々非常に大きな意味と重要性を持つことになると考えられます。**

# クラウド利用の初期に気をつけたいこと

オンプレミスをはじめとした、旧来的なインフラ中心に運用する企業 (チーム) にとってクラウドでサービスをはじめることは比較的大きな冒険です。

そのため、多くの場合まずテスト的にクラウド利用をはじめると思います。

**正直なところ、この時点でアカウント自体もテスト専用アカウントとしておくことが非常に重要と考えます。<font color="red">クラウドサービスの中にはアカウントに対してグローバルであり、後から変更が難しいリソースなどが存在する</font>ことがあり、ある程度決め込んで使い始めなければまずいケースが存在するからです。**

# ネーミング不統一のままクラウド利用を本格化すると何が起こるか

たとえば、あるスモールサービスを開始する時に、AWSで2台のEC2サーバを作ったとします。
それぞれネーミングは下記の通りです。

- WEB01
- DB01

これらのサーバが何をしているのか、見ればだいたい分かると思いますが、このまま進めると以下のような問題が生じてくることは明白です。

- とりあえず動くものを作ったが、ステージング・開発環境は…?
- 別案件 (アプリケーション) のWEB01を追加したいが…?
- DB01をRDSに移管したいが、これは同じDB01という名前でいいか…?

また、先ほど**後から変更が難しいリソース**について書きましたが、**GCPを利用すると仕様的にそもそも名前は変更できません。(2020年6月現在)**

直近の担当案件で採用されていたこともあり、私は自宅でもGCPをサブで利用しています。
本項ではGCP利用を題材に、私が自宅利用で採用しており、ビジネスレベルでも運用可能と考えるネーミングルールについて紹介します。

# コンピュータにおけるネーミングの基本

そもそも、プログラム等でネーミングに利用されている命名規則はおよそ下記の4通りです。

#### camelCase
多くのオブジェクト指向言語でメソッド名として使われている記法です。
各単語の最初の一文字目を大文字にしますが、最初の一単語だけは全て小文字です。

#### PascalCase
多くの言語で camelCase の一種 (または等価) と見なされる記法です。
全ての単語の一文字目を大文字にします。アッパーキャメルケースと呼ばれることもあります。

#### snake_case
MySQLなどのデータベースで、テーブル名・カラム名の記載に使われる記法です。
各単語をアンダーバーでつなぎます。

全くの余談ですが、SQLでは名前として大文字・小文字を区別しません。
また、ハイフンを使うと一部の処理系では不具合を生じます。

#### kebab-case
主にHTMLのクラス名などに用いられている形式です。
複数の単語をハイフンでつなぎます。

## どの記法がなじむか ?

これはすでに一般的なプラクティスも含め、まずは **<font color="red">kebab-case</font>** だと思います。

理由としては、

- API使用を前提とすれば、WEBで解釈可能なものをチョイスした方が良い (→ HTML)
- 上の観点に立つと、URLでの大文字・小文字の区別についてがやや心に引っかかる
- AWS・GCP両対応を考えると、 snake_case は使えない  
**(= GCPではリソース名にアンダーバーが使えない仕様)**
- ネット検索で調べると、これを採用している企業が多い
- camelCase で長い名前を書いてみると、とても読みづらい

私のかつての担当案件でも **kebab-case** を採用していました。

当時から記法自体についてのネガティブ意見はなかったのと、現状の**私の利用範囲でも不都合は出ていない**ことから kebab-case が良いと判断しています。

# 何を表現すべきか

### アプリケーション名 (システム名)

たとえば、 `alpha` という名前のアプリケーションを開発したとしたら、そのシステムのメインの名前は端的に「alpha」がいいでしょう。

ただし、ここで考えておかないといけないのは、アプリケーションに依存しないシステムについてです。

例えば簡単なところでは、複数のティザーサイトを収容したWEBサーバなどでしょうか。
こうしたものは「teaser-sites-web」などの名付けが考えられます。

私はアプリケーションに依存しないシステムの特質を、以下のような指標で捉えています。

- 何が入っていて
- 誰が (どの部署が)
- いつ (頻度)
- どんな目的で

利用するか… というような一連の事実です。

**もし、明確にシステムに名付けがされていない場合、この中から意味的に指標を選んで名付けをするプラクティスは考えられ得ます。**

```
例:
weekly-sales-total
(営業部の週次売上を計算するシステム)
```

こうした一連のシステムの特性にちなんだメインの名前を、『システム名』と呼ぶことにしてこれより以下では、

`[system-name]`

と記載していきたいと思います。

#### 共通システムについての考慮

`[system-name]` があるクラウドアカウント全体に渡って利用されるケースを考えます。

例えば、 特定のカテゴリ名を持たない複数のアプリケーションで稼働するマイクロサービスを開発します。
この提供のために、新しいGCPのクラウドアカウントID `var-tools` を取得しました。全てのアプリケーションは単一の GKE (Google Kebernetes Engine) クラスタに収容されています。

このクラスタ名について考えます。
この場合は単純に「var-tools」でもいいでしょう。

ただし、**その名前を見ても明らかに複数のサービス群を指していると認識できない場合**は、そこにあえてカテゴリ名を付与することで、以下のような名前にしたくなるかもしれません。

- common-bravo  
または
- bravo-common

「common」「all」などの**単語を前後に付加したいケースはしばしばやって来るのですが、<font color="red">前か後か</font>を早い段階でよく決めておかないと、システム規模が大きくなってきた時に混乱を来すことに注意が必要です。**

また、「common」「all」などという単語自体もとても曖昧で、かつ多用しやすいものです。
こうした**用語の利用ルール**自体を、関係者内で認識共有しておいた方が良いでしょう。

### 環境名

これは、本番・ステージング・開発などの別のことです。
私は以下のような5つの名前のいずれかを付けるルールにしています。

- pro　…　本番環境
- stg　…　ステージング環境
- dev　…　開発環境
- test　…　検証環境
- whole　…　GCPプロジェクト全体に関わるもの

### リソース名

ここでいうリソースとは、先ほど例に挙げた GKE (Google Kebernetes Engine) などのクラウドリソース種のことです。

名前にリソース種を入れるのは、パッと考えると不要と思えるかもしれません。
ただ、いつもクラウドのWEB UIを見ながら話をするわけではないですし、特に以下のような事情を考えるとこの要素をネーミングに含めることが必要と分かります。

- あるリソースを、他のクラウドに移行するケース (例: GCP→AWS)
- あるリソースを、他のリソースに移行するケース (例: redisをEC2→ElastiCache)
- 同じ名前・性質のものであるが、複数リソースに存在するもの

これはネーミングとして重きをおく部分ではないので、環境と同じように3〜4文字で表したいところです。
GCPについては、**公式で積極的に略語を使っている**ようですので、多くはそれをそのまま用いれば良いでしょう。

以下のような要領です。

- gae　…　Google App Engine
- gce　…　Google Compute Engine
- gke　…　Google Kebernetes Engine
- gcf　…　Google Cloud Function

# 表現のプライオリティから形式を決める

ここまで検討してきた、

`[system-name]`
`[環境名]`
`[リソース名]`

を組み合わせることで実際の命名を作るのですが、順番を決める必要があります。
ここは好みというか使いやすさだと考えますが、

- 何が最も必要か？
- WEB UIでの検索性はどうか？

という視座に立つと、 **[system-name] [環境名] のいずれかを先頭**に持って来るのが良いでしょう。[環境名] を持ってくる理由は、ステージング/本番/開発をWEB UI上で名前で分けてソートできるからです。

私は以下のようにしています。

```
pro-charlie-web-gce
[環境名]-[system-name]-[リソース名]
```

# 号機採番について

号機採番というのは何かというと、「WEB01」のような名前の「01」の部分のことです。
(この部分を実際何と呼ぶのか、調べても私にはちょっと分かりませんでした…)

GCPの**名前を後から変更できない**という性質上、この番号がないとクラウドでよくあるリソースの作り直しに際して不都合を生じることになります。

そのため、私は号機採番は必須というルールにしています。
リソースを作り直したときに 01 → 02 → 03… のように基本的にはインクリメントします。

号機採番を含めたネーミングは以下のようになります。

```
pro-charlie-web01-gce
[環境名]-[system-name][号機]-[リソース名]
```

### 採番ルール

もし号機採番というものを採用するなら、番号の運用パターンについてはよく考慮しておいた方が良いでしょう。

私は以下のように決めています。

- 号機は基本的に一意性を保つために存在する
- 番号自体には意味を持たせない  
(例: 偶数番号のインスタンスは性能を上げる…などはNG)
- 飛び番・抜け番はあり得る
- 基本はインクリメントだが、デクリメントもあり得る
- クラスタを構成するリソースでは識別子になる
- クラスタを構成しないリソースでは世代を示す
- あるリソースの中に他のリソースが紐付く場合は、元リソースの採番を取り除く  
(例: GCEのIPアドレス)

# 実例

ここからは、これまで利用したことのあるリソースごとに実例にそって紹介します。

#### VPCネットワーク

```
whole-delta-service-vpc
```

- 基本的にVPCに作り直しはないので、号機採番はありません。

#### Google Compute Engine

```
pro-delta-service-web01-gce
stg-delta-service-web01-gce
```

#### Google Compute Engine (インスタンスグループ)

```
pro-delta-service-web-group01-grp
stg-delta-service-web-group01-grp
```

- VMを入れる箱という位置づけのリソースなので、「web」に対する採番は除去します。

#### Google Compute Engine (IPアドレス)

```
pro-delta-service-web-gce-ip01-ip
stg-delta-service-web-gce-ip01-ip
```

- 「pro-delta-service-web01-gce」に割り当てるIPを想定しています。
- GCE も再作成があり得るので、「web」に対する採番は除去します。

#### Google Kubernetes Engine

```
whole-delta-service-cluster01-gke
```

- 単一のクラスタをプロジェクト全体で運用する場合

#### Google Kubernetes Engine (ノードプール)

```
whole-delta-service-cluster01-gke-pool01-pool
```

- 「project-delta-service-cluster01-gke」に適用するプールを想定しています。
- クラスタもプールも複数になり得るので、採番も多重にします。

#### Google Cloud Load Balancing

```
pro-delta-service-site01-glb
stg-delta-service-site01-glb
```

#### Google Cloud SQL

```
pro-delta-service-db01-sql
stg-delta-service-db01-sql
```

#### Google Cloud Storage (バケット)

```
pro-delta-service-gcs
stg-delta-service-gcs
```

- 基本的にStorageバケットに作り直しはないので、号機採番はありません。

#### IAM (サービスアカウント)

```
pro-delta-devteam01-gsa
stg-delta-devteam01-gsa
```

- 名前の文字列がIDになるため、仕様として30文字以内にする必要があります。

# おわりに

もちろん、クラウドで必要なことが名前だけで表せるはずもなく、その他のタグやメタデータと併せて設計することは重要でしょう。

ただ基本としてネーミングを疎かにすると、クラウドの利用規模が大きくなってきた時、管理不能に陥ることは当然起こるべきと認識すべきです。

ネーミングについては、

- 利用クラウドサービスの全体感を掴んで考慮する
- 自社 (チーム) のサービスで何が必要になるか洗い出す
- シンプルさと拡張可能性のバランス

など、一定の普遍性を持たせながらも個別的に検討する必要があると考えます。

Fin ❤︎