Excel構成管理から抜け出すためのExcelの使い方




# はじめに

みなさん、Infrastructure As Code してますか？　はい、私もしています。
みなさん、パラメーターシートでEXCEL使ってますか？　はい、私も使っています。
みなさん、パラメーターシートと実環境の同期、できでますか？　……

そんな話題です。

# 課題

先のくだりは、何もクラウドに限った話ではなく、昔からのあるある話として語り継がれていると思います。

クラウドはインフラ構成をコードで表現できるので、それがパラメーターだという意見は基本的に合意なのですが、やはり見慣れたEXCELでパラメーター管理するプロジェクトや組織は多い、というのが現状だと思います。
※老害や老害や老害などの理由があると思いますが、ここでは割愛しますw

Githubなどでアプリケーションのコードを管理するのと同じように、インフラ構成も管理できるようになったはずなのに、EXCELはバイナリだから差分が見えない（確認方法はありますがGithubネイティブではない、という意味です）。または、そのコードで表現したパラメーターとEXCELのパラメーターシート、最終的にはそれらと実環境が一致していることをどうやって担保するか、という課題を抱えている、という話は、よくあることだと思います。

# 解決策
で、どうしたか、という話なのですが、、、

ツール、作りました。以上。


…ではつまらないので、
どんなコンセプトのツールなのか、どう使うことを想定しているかをご紹介したいと思います。

## ツール概要
JSONファイルをinputにし、terraform, awspec, EXCELパラメーターシートを自動生成します。
JSONファイルは独自フォーマットを定義してます。
Go言語で作成しました。

想定運用フローは、下図のような感じです。terraformの状態管理ファイル(tfstate)は所定のS3バケットに自動的にUpすることで、複数人で開発する際にいちいちGithubからpullしてこなくていいようにしています（別に新しい話ではないですが…）。

`大事なのは、全ての変更はJSONファイルで行い、ツール経由で生成すること`です。
要するに、`EXCELはViewerとしてのみ利用し、編集させないのがポイント`です。
こうすることで、全ての成果物と実環境の整合性が保たれることになります。

![](https://s3-ap-northeast-1.amazonaws.com/kaojitario7/qiita-image/20171220/overview.JPG )

## サンプル
本記事ではEIPを例にinput/outputのサンプルをご紹介します。

### inputのJSONファイル
こんな感じでJSONを作ります。配列形式ですので、複数のEIPを設定可能です。

```json
{
  "eip": [
    {
      "resource_name" : "test_eip01",
      "vpc_flg" : "true",
      "remark" : "NATゲートウェイ01用"
    },
    {
      "resource_name" : "test_eip02",
      "vpc_flg" : "true",
      "remark" : "NATゲートウェイ02用"
    }
  ]
}
```


### terraform
```
resource "aws_eip" "test_eip01" {
    vpc = true
}
output "test_eip01" {
    value = "${aws_eip.test_eip01.public_ip}"
}

resource "aws_eip" "test_eip02" {
    vpc = true
}
output "test_eip02" {
    value = "${aws_eip.test.public_ip}"
}
```

outputセクションを設けているのは、awspecコードの置換（後述）を行うためです。


### awspec

```ruby
require 'spec_helper'

# Test for EIP which named test_eip01
describe eip('<tmpl>test_eip01</tmpl>') do
  it { should exist }
  it { should belong_to_domain('vpc') }
end
# Test for EIP which named ncis-vpc01_eip02
describe eip('<tmpl>test_eip02</tmpl>') do
  it { should exist }
  it { should belong_to_domain('vpc') }
end
```

awspecでは、EIPはリソースIDを引数にとるので、プロビジョン前にその値を知ることはできません。
よって、いったん置換文字列で挟んでおき、プロビジョン後にterraformのoutputセクションの情報をもとにリソースIDに置換する方式を採用しています。

### EXCEL
イメージこんな感じです。Instance Name列は、EC2に紐づけるものである場合に、そのEC2 Nameが設定されます。

![](https://s3-ap-northeast-1.amazonaws.com/kaojitario7/qiita-image/20171220/xlsx_image.JPG )

EIPだけであれば、プロパティも少ないので、手作業でも何とかなるレベルですが、他のリソースもたくさんあるので、これらすべての整合性を取ろうとすると、やはりこのようなツールから生成するのが望ましいのでは、と感じています。


## 採用技術の根拠を少し
### なぜJSONか？
* JSONは構造が規定されているので、EXCELのように行や列の使い方などのルールを設ける必要がなく、作業の標準化が可能になる。
  ※ EXCELフォーマットのバリデーションチェックに忙殺されたくなかったのが本音…

### なぜGo言語か？
* Goはクロスコンパイル環境が提供されているので、windows(32ビット、64ビット)やlinux(32ビット、64ビット)版のツールを簡単に生成できるのが魅力的だった
* 出来上がるツールは1バイナリ―ファイルなので、利用する際、追加で何かをインストールする必要がなく、利用を開始するまでのハードルが下げることができる

### なぜCFnではなくTerraformか？
* スタックテンプレート(.tfファイル)を複数分割してもパラメーターの受け渡しが可能（楽）
* Dry runや差分実行がやりやすい

ここは好みの問題もあると思います。最近のCFnも進化しているので、CFnでもよかったかな、という思いもあります。

### なぜawspecか？
* スモールスタートする際に極力イチからつくるのは避けたかったから

ぶっちゃけ、対応していないリソースやプロパティがあったりして、awspecではすべてカバーしきれないので、その場合はaws sdk for rubyでdescribeする形にしています。
（だったら最初からdescribeする方式しておけばよかったかな、と思ってたりもするのは内緒の話…）



## 効果
完全とまではいきませんが、上記課題を解決することができました。

また、terraformはDry run(plan)ができるので、`定期的に本番環境にplanすれば、予期せぬ変更がされていないかを確認することもできます`。
ちなみに、テストコードも合わせて作っているのは、クロスチェックするためです。terraform設定の理解が誤っていて、実環境との相違を発生させないため、です。
これは、付加価値かな、と感じています。

そして、再認識したのですが、"ViewerとしてのEXCEL"は素晴らしいです。
JSONで構造化されたリストでも十分見やすいのですが、やはり一覧化されて他リソースと並べて比較しながらパラメーターをチェックできたりするのは、レビュー時などではとても魅力的だと改めて感じました。

# さいごに
残念ながら、諸々の事情があり、ツール実体やソースコードはまだ公開できないのですが、実際にツールを使ってみたい！という方がいらっしゃれば、個別にご連絡ください！！
一緒にこのツールを育てていただける方も大歓迎です。

クラウド使い始めてみたけど、構成管理という面で同じような課題を抱えている方の一助になれば幸いです。

なお、本記事の内容はあくまで個人の見解であり、所属組織の意見を代表するものではありません（念のため）。