【Ubuntu】 /etc/netplan/50-cloud-init.yamlを編集するの止めろ

この記事は**SFC-RG AdventCalender 14日目**です．

## まえがき
筆者反省の記録．

### 注意
cloud-init/netplanのアーキテクチャについては説明しません．

### 対象者
- `Ubuntu Server 18.04~` で初回起動時にIPアドレスを設定したい！ 人
- `/etc/netplan/50-cloud-init.yaml`

## 本文

### Netplanについて

みなさん [netplan](https://netplan.io)使ってますか？

Ubuntu 16.10からnetplanが導入され，執筆現在ではすっかり浸透しましたよね．
それまでUbuntu/debianで固定IPアドレス設定と言えば`/etc/network/interfaces`でしたが， netplanが導入されてから記法や設定変更フローが洗練され非常にユーザーフレンドリーになりました．

よく巷で解説されている設定方法は以下のようになります．
参考： [Ubuntu Forum](https://askubuntu.com/questions/1029531/how-to-setup-a-static-ip-on-ubuntu-server-18-04/1057594)

かいつまんで説明すると以下の様になります．


①初回ログイン後，以下のファイルを編集．

```yaml:/etc/netplan/50-cloud-init.yaml
# This file is generated from information provided by
# the datasource.  Changes to it will not persist across an instance.
# To disable cloud-init's network configuration capabilities, write a file
# /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg with the following:
# network: {config: disabled}
network:
ethernets:
    ens0:
        dhcp4: false
        addresses:
        - 192.0.2.2/25
        - 2001:db8:2005::334/64
        gateway4: 192.0.2.1
        gateway6: 2001:db8:2005::1
        nameservers:
            addresses:
            - 8.8.8.8
            search:
            - example.com
version: 2

```

② 変更をnetplan cliから適用

```bash:~/
$ sudo netplan apply
```



### `vim /etc/netplan/50-cloud-init.yaml`

「Ubuntuの固定アドレス設定？ /etc/netplan/50-cloud-init.yamlを編集すれば良いんでしょ？」

まあそうなんですが，間違ってるっちゃ間違ってます． 
(VMのコピーや移動を行わない限り実運用上問題ありません)

そもとも`50-cloud-init`って何やねんって思いませんか．

### netplanは`/etc/netplan/*.yaml`を全部参照する

[netplanの公式ドキュメント](https://netplan.io/reference)には以下のような記述があります

> All /{lib,etc,run}/netplan/*.yaml are considered. Lexicographically later files (regardless of in which directory they are) amend (new mapping keys) or override (same mapping keys) previous ones.


平たく言うと， 
- **`/etc/netplan/*.yaml`を全部参照**する．
- **アルファベット順で読み込んでいって， 上書き**していく．

ということのようです．


### `50-cloud-init.yaml`は人間が触るファイルじゃない．

また，以下のようにも記述があります．
> Netplan reads network configuration from /etc/netplan/*.yaml which are written by administrators, installers, cloud image instantiations, or other OS deployments. 

netplanの設定ファイル群は我々のような管理者(人間)以外にも， OSのインストーラーや`cloud image instantiations`により編集されることがあるということです．


つまり，**`/etc/netplan/50-cloud-init.yaml`は我々人類が触るファイルではなく，その名の通り`cloud-init`によって生成されたファイル**なんです．


#### っていうか書いてある
```yaml:/etc/netplan/50-cloud-init.yaml
# This file is generated from information provided by
# the datasource.  Changes to it will not persist across an instance.
# To disable cloud-init's network configuration capabilities, write a file
# /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg with the following:
# network: {config: disabled}
```

もろ書いてあります...



### `cloud-init`について
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94774/9d827e33-ea46-2291-cd39-848cd0d2b659.png)


`cloud-init`はCloud環境向けの環境設定フレームワークです，ネットワークの設定はもちろん，初期ID/PWやhostname，初回起動時のみに実行したい処理などを記述しておく事ができます．

AWSのようなパブリッククラウド環境はもちろんのこと(そもそもcloud-initはec2-initという名前だったそうです)
[cloud-initを使ったLinux OSの初期設定](https://qiita.com/yamada-hakase/items/40fa2cbb5ed669aaa85b)

ローカルマシンのインストールにも使用する事ができます．
[第561回　ローカルインストール時もcloud-initを活用する](https://gihyo.jp/admin/serial/01/ubuntu-recipe/0561)

*(かいつまんだ使い方はまた別日に書きます．)*


### `/etc/netplan/50-cloud-init.yaml`を編集すると何が起こるか

通常，そのまま利用するだけなら上書きされたり無効化されたりすることはありません．(執筆現在筆者が触っている環境では)
ただそもそもこれは人間による編集を想定したファイルではないのでVMをコピーした時など，`cloud-init`の処理が再度行われるケースがあります． 
このような原因で`cloud-init`が再度実行された場合，もともとあった`50-cloud-init`は**当然の如く上書きされ，元の設定は喪失します**．





### じゃあどうすればいいのか．
`50-cloud-init.yaml`には触らず，アルファベット順で後になるような名前の新しいファイルを作成して下さい．


```yaml:/etc/netplan/99-manual.yaml
network:
    ethernets:
        ens0:
            dhcp4: false
            addresses:
            - 192.0.2.2/25
            - 2001:db8:2005::334/64
            gateway4: 192.0.2.1
            gateway6: 2001:db8:2005::1
            nameservers:
                addresses:
                - 8.8.8.8
                search:
                - example.com
    version: 2
```

ちなみに仮に以下の様に`50-cloud-init.yaml`が残っていたとしても競合する部分はしっかり上書きされます．

```yaml:/etc/netplan/50-cloud-init.yaml
# This file is generated from information provided by
# the datasource.  Changes to it will not persist across an instance.
# To disable cloud-init's network configuration capabilities, write a file
# /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg with the following:
# network: {config: disabled}
network:
    ethernets:
        ens0:
            dhcp4: true
    version: 2
```





## まとめ．

- `/etc/netplan/50-cloud-init.yaml`を編集するのは止めましょう．
- 新しくアルファベット順で後になるような`/etc/netplan/*.yaml`を作りましょう．
    - 例えば`/etc/netplan/99-cloud-init.yaml`のような

- **今まで間違えていた人はcloud-initくんに謝りましょう**
 - ぼくも謝ります．怖がらずに英語をちゃんと読みます．