サーバの/etcを自動的にGitとかにコミットとかプッシュしてくれるetckeeperを使う

# はじめに
インフラを担当しています。
一人が管理できるホストには限りがあるなと思っていて、補助ツールがなければ10台ぐらいが精一杯かと思っています。
補助ツールを使うことで100台ぐらいまでは行けるんじゃないかと思っていて、そのためのツールを探していました。

普段のサーバ管理でやっていることを書いてみます。

* チューニングなどでconfの調整
* 過去に他のホストで導入した設定の適用
* バックアップと復元、移設
 
これらはetcを管理することで実現できそうですね。

過去にはSubversionを使って手作業で管理していましたが、この辺りを(半)自動化してくれるetckeeperというツールがあるということで試してみました。

# インストールと初期設定
yumにもaptにもあります。

CentOSの場合にはepelを入れておきます。

```bash:CentOS
$ sudo yum update && sudo yum install epel-release
$ sudo yum install -y etckeeper
```

```bash:Ubuntu
$ sudo apt-get install -y etckeeper
```

設定ファイルはデフォルトで /etc/etckeeper/etckeeper.conf にあります。Ubuntu系はデフォルトのコンフィグがbazaarになっているのでgitにしました。

```conf:/etc/etckeeper/etckeeper.conf
(中略)
VCS="git"
#VCS="bzr"
```

今回はバックアップも兼ねているので外部ホストにリポジトリを持たせプッシュします。

自動プッシュについては過去のバージョンでは自前でフックを書いていたようです。
> リモートリポジトリに自動的にプッシュ
> https://wiki.archlinuxjp.org/index.php/Etckeeper#.E3.83.AA.E3.83.A2.E3.83.BC.E3.83.88.E3.83.AA.E3.83.9D.E3.82.B8.E3.83.88.E3.83.AA.E3.81.AB.E8.87.AA.E5.8B.95.E7.9A.84.E3.81.AB.E3.83.97.E3.83.83.E3.82.B7.E3.83.A5

最近ではデフォルトでフックが付いてきているようです。コンフィグにあるPUSH_REMOTEを設定します。

```conf:/etc/etckeeper/etckeeper.conf
(中略)
# To push each commit to a remote, put the name of the remote here.
# (eg, "origin" for git).
PUSH_REMOTE="origin"
```

ワンライナー

```bash
$ sudo sed -i -e 's/PUSH_REMOTE=""/PUSH_REMOTE="origin"/g' /etc/etckeeper/etckeeper.conf
```

# リポジトリのinitなど

```bash
$ cd /etc
$ sudo etckeeper init
```

# origin追加

```bash
$ sudo git remote add origin gitのURL
```

# コミット

```bash
$ sudo etckeeper commit -m 'first commit'
```

# その他のコマンド
`etckeeper vcs`を行うとVCSのサブコマンドが見れます。

<img width="598" alt="Screen Shot 2017-05-16 at 11.24.15.png" src="https://qiita-image-store.s3.amazonaws.com/0/47327/551ab585-13c8-1bd4-1e69-d2a6514829ca.png">

# .gitディレクトリの確認など
基本的に/etcを管理するので、etckeeperコマンドの実行はroot権限で行います。
またetckeeper自体は他のVCSのラッパーなので、本質的には`/etc`に`.git`ディレクトリを作成し、そこを管理することになります。
Zshなどを使っているとGitのstatusなどを監視してくれる仕組みがあり便利です。しかしその場合には一般ユーザ権限で`.git`を見ることが必要となります。
しかしデフォルトでは`.git`ディレクトリはroot権限となっているので、このディレクトリのグループに読み込み（＋実行）権限を出します。

```bash
$ sudo find ./ -type d -exec chmod g+rx {} \;
$ sudo find ./ -type f -exec chmod g+r {} \;
```

<img width="450" alt="Screen Shot 2017-05-16 at 11.27.58.png" src="https://qiita-image-store.s3.amazonaws.com/0/47327/dc9beab8-38a4-e7b2-4447-4039d9d2ac73.png">

[rootグループに属しているのに見れないファイルのディレクトリのパーミッションをfindで再帰的に一括変更する](http://qiita.com/yousan/items/186cb411df453c879ae9)

セキュリティポリシーとの兼ね合いがあると思いますのでそのあたりはお好みで。

# cron
CentOSとUbuntuではパッケージのインストール時に /etc/cron.daily にetckeeperのスクリプトが入りました。
このファイルのおかげで毎日定期でコミット(+プッシュ)されます。


# 実用
今回の導入ではGitのリポジトリをbitbucketに作成しました。

ホスト名でリポジトリを作成しています。

![Screen Shot 2016-04-18 at 9.54.01 AM.png](https://qiita-image-store.s3.amazonaws.com/0/47327/33f77132-745e-6212-4431-505b48f99cca.png)

originの登録。

```bash
$ sudo git remote add origin git@bitbucket.org:yousan000/`hostname`.git
```

秘密鍵を作成してbitbucketのアカウントに登録します。

```bash
$ sudo sh -c 'ssh-keygen ; less /root/.ssh/id_rsa.pub'
```

うまく行けばbitbuket側にetcがpushされます。

# ![Screen Shot 2016-04-18 at 9.56.36 AM.png](https://qiita-image-store.s3.amazonaws.com/0/47327/b9336c67-aeed-28f8-5610-a0abd4fcdc34.png)

# その他
## 動作テスト
なんだかんだで結構手こずりました。うまく動くか試しました。
/etcに少し変更を加えてコミットするワンライナーです。

```bash
$ sudo sh -c 'echo $RANDOM > /etc/hoge.txt; etckeeper commit -m "test commit"'
```

## 感想
etckeeper便利そうですね。もう全部のホストでこれに乗り換えようと思っています。
元々Subversionを利用していた頃からでしたが、サーバの/etcをバージョン管理する事はセキュリティリスクが伴います。管理下に置かれるファイルはpasswdを始めldapのsecretなんて超重要なファイルもあったりします。その辺りはセキュリティリスクとファイル保全のリスクを天秤にかけて適宜管理していく必要があります。.gitignoreを使うのも良いと思います。
Subversionではデフォルトでパスワードを平文保存しようとします。一つのリポジトリ内にディレクトリで切ってホスト毎に管理をしていた時期もありますが、確実に自分の管理下にあると確信が持てないとこれもリスクになります。

今回の途中では秘密鍵により自動pushを実現しましたが、ホスト毎にgitのアカウントを換える必要があるかも知れません。
bitbucketのようなサービスの場合、一つのアカウントに登録された秘密鍵では複数のリポジトリにアクセスできてしまいますから注意が必要です。
お客さんがroot権限を持っている場合には秘密鍵が漏れる前提でリポジトリを構成すべきで、リポジトリ名にAPIキーのようなハッシュを含めるか、秘密鍵とgitユーザ、リポジトリの管理を分けると良いでしょう。

という心配事はありますが、総じて便利そうです。自動化できるのはとてもありがたいですね。
OS Xのbrewで作成される/usr/local/etcや~/も管理できそうなのでトライしてみようと思います。