今まで手作業でインフラ構築をしていた組織がAnsibleを使うときに気をつけて欲しいこと

この記事は[ Ansible 2 Advent Calendar 2019 24日目 ](https://qiita.com/advent-calendar/2019/ansible2)の記事です。

# 自己紹介+この記事の説明

サーバーサイドのインフラの設計や構築周りをやっているあんでぃーと申します。
どちらかというと大手(？)SIerに勤めています。

弊社では、一昨年〜去年あたりから色々なプロジェクト(以下`PJ`)で「Ansibleを使いましょう」という指令が発射されるようになりました。
それまでのやり方はウォーターフォール型で、

- Excelで設計書作ってレビューして
- Excelで構築手順書を作ってレビューして
- 単体テスト仕様書を作ってレビューして
- 構築手順書と設計書を見ながら実機をカチャカチャして構築して
- 単体テスト仕様書と設計書を見ながら実機をカチャカチャして正しく構築されてることを確認して

といった感じのまごころドリブンなやり方です。
まぁ複数人でシステムを作るにあたっては一般的(であろう/だった？)やり方ですね。

我々はこの方式を変更してAnsibleを使う必要がありましたが、もちろんスムーズにいくわけがなく、現場では様々な悩みが発生しました。
具体例としては以下のようなものが挙げられます。

- PJメンバーが…
    - PJのスケジュールにうまく適合できずいっぱい残業をしている
    - Ansibleを適用する領域がごく一部になり、結果今までとあまり変わってない
    - あるパラメータを変更するとき、設計書とコードを両方変更しないといけなくてつらい…
    - あれ…？このPJでAnsibleわかる人…俺しかいなくね？
- PJマネージャが…
    - 今までのマネジメントのやり方を変えず「Ansible使えるところは使って」スタイル
        - Ansibleを使うことによるメリット(構築自動化による時間短縮、変更への強さ、等)を享受しきれない
    - そもそも「Ansibleができること」を理解できていない
        - 「Ansibleに期待すること」と「実際できること」にギャップがあることで、計画の見直しやリカバリ作業が必要になる
        - (PJマネージャが理解することをあきらめた場合) PJメンバへの丸投げが発生する

そこで今回は「なぜPJでAnsibleをうまく使えないのか？どうやったらできるのか？」について、プロジェクトマネジメント(以下`PM`)的な視点から考えてみようと思い、この記事を書くことにしました。
切り口をPMにしたのは、上記のような悩みが、「Ansibleで構築を行うこと」そのものではなく「Ansibleを使うときにPJの進め方(=PM)をどうすれば良いのか」を把握できていないことに起因していると考えたからです。

学生さんや既に自動化バリバリな方にとってはつまらない内容かもしれませんが、上記のような悩みを抱える、私と同じような境遇の方々に何らかの気付きを与えられることを祈って頭の中を吐き出してみます。

なお先に断っておきますが、私は専門家でも何でも無いただの一般男性です。なので記載の内容は間違っている可能性があります。
鵜呑みにはせず、参考情報として使えるところは使っていただけると嬉しいです。
「ここ違くね？」「これも気をつけないとダメじゃね？」なことがあれば皆様の意見も聞きたいので是非コメント頂ければ嬉しいです。

# Main

- ここから、[PMBOK](https://ja.wikipedia.org/wiki/PMBOK)のPM知識エリア(以下の10個)をベースに「Ansibleを使う場合、これまでのPMから何を変えなければならないのか」を書いていきます
    - 統合
    - スコープ
    - スケジュール
    - コスト
    - 品質
    - 資源
    - コミュニケーション
    - リスク
    - 調達
    - ステークホルダー
- PJのスタイルはウォーターフォール型、自動化範囲は構築フェーズ を想定しています

## 統合

### 成果物

Ansibleを使う場合、成果物(納品物)が変化する可能性があります。
納品物は顧客合意が発生するはずなので、PJの早い段階で認識し、考慮しておく必要があるでしょう。

Ansibleを使わない場合、成果物は「設計書」や「構築手順書」あたりになるかと思いますが、Ansible Playbookはこれらの機能を持っています。
そのため、Ansibleを使うPJの場合、成果物はPlaybookそのものにするのが良いと思います。
→ ただしPlaybookに書ききれない情報について、設計書や手順書として作成するのはOKです

とにかく、Playbookが持つ情報と設計書が持つ情報が重複しないようにすることが重要です。
重複している場合、変更要求に対して修正する成果物が多くなり、パフォーマンスが低下してしまいます。

「Ansibleは使うけど、どうしても従来の形の設計書を納品する必要がある場合」は、納品のタイミングをできるだけ後ろにずらすなどで工夫するのが良いと思います。
→ 構築フェーズはPlaybookを中心に進め、設計情報が固まった段階で成果物としての設計書を作成することで、設計書に対する変更要求の数を減らす
あるいは、Playbookを解析して設計書を生成するようなツールを用意するのも良いかもしれません。

### 変更管理

Playbookはyamlという形式のテキストで実装されるため、Playbookの変更管理はGitのようなバージョン管理システムと相性が良いです。
Gitと聞くとアレルギー反応を示す方もまだいらっしゃいますが、ただファイルを管理するだけならとっても簡単です、みんな使っていて実績もあります、安心して勉強しましょう。

コードのバージョン管理ができれば良いので他のツール(SVNとか)でもかまいませんが、Gitをおすすめする理由は流行していることと、Pull Requestの存在によりコードレビューをチームに導入しやすいことが挙げられます。
「コードレビューを行う文化」は、これまでコードを書いたことの無いインフラ屋さんには存在しないものだと思いますが、このPull Requestを前提としたフローやシステムを整備することでレビューの仕組みを簡単に作ることが可能です。

## スコープ

スコープについては基本的に変わりません。
手作業でシステムを構築するにしろ、Ansibleで構築するにしろ、システムに要求される機能は同じはずだからです。
Ansibleはシステムを構築する手段であって目的ではありません。

ただし自動化によって得られる利点があるなら、追加のスコープとなる可能性はあると思います。
何が利点になるのかはPJによって異なると思うので一概にはいえませんが、例えば「全部Playbookで記述することで作り直しが簡単にできる」とか「変更要求に強い」とかの、IaCなメリットを狙うことになるかと思います。

## スケジュール

スケジュールについては結構大きく変わります。
現場でPJメンバが苦しむところの多くはここかと思います。

### アクティビティの定義

「アクティビティ」とは成果物を生成するために必要な作業のことです。
Ansibleを使うの場合、設計〜構築周りのアクティビティが変化します。

自動化の度合いによりアクティビティは異なりますが、単純な例を挙げれば以下のようになるかと思います。

|フェーズ|アクティビティ - 従来|アクティビティ - Ansible|
|---|---|---|
|設計|設計書作成<br>設計書レビュー|(設計確認)|
|構築準備|構築手順書作成<br>手順書レビュー<br>(検証環境での手順確認)|Playbook作成<br>Playbook検証環境準備<br>検証環境での動作確認<br>Playbookレビュー|
|構築|構築作業|Ansible実行できるまでの構築作業<br>Playbook実行|

※ カッコ書きの部分は場合によっては不要かもしれません

ここでのポイントは以下です。

- 設計情報はPlaybookに記載されるため、設計フェーズと構築準備フェーズは区別せず同時進行したいです
    - 設計フェーズを先に持ってきて、その後Playbookを作るアクティビティにしてしまうと、上述した「設計書とPlaybookが別々に出来上がる」状態になってしまう恐れがあるためです
- 構築準備フェーズでPlaybookの検証環境が必要です
    - 当たり前の話ですが、構築準備フェーズのアウトプットは構築フェーズで使えるものになっている必要があります
    - よって、Ansibleを用いる場合、Playbookは事前になるべく本番と同じ環境で動作確認がされたものをアウトプットするべきです
    - 「動作確認できていないPlaybookを使った結果エラーして構築が進まない！」という事象が起きないようにコントロールします
- Playbookのレビューを忘れないようにしましょう
    - Playbookをレビューしないことは「手順書を作ってレビューしない」と同義です
- Ansibleを使う場合でも、手作業でやらなければならない範囲はあります
    - 例えばオンプレの場合、OSインストールやsshを使えるようにするところまではAnsibleでは実施できません

### 各フェーズの所要期間

従来の「設計」+「構築準備」フェーズは、Ansibleを使うPJでは「Playbookの作成」に置き換わり、必要な期間は長くなります。
そして、事前に動作確認が行われたPlaybookを用いるという前提なので、構築にかける時間は短くなります。
以下のようなイメージです。

![スケジュール変化の図](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434589/801476d4-9a12-bb84-3917-711a2d71a4e2.png)

特に注目したいのは、設計〜構築準備フェーズが長く必要であることです。
ここを従来のPMのまま(図の上側)スケジュールを立ててしまうと、「Playbookの作成+検証」に必要な期間はどう見ても足りません。

弊社ではここを辛いと思っている人(特に若手)が多いような印象です。
PJスケジュールが計画段階でそもそも間違っている+どうリスケすれば良いのか分からないので、終わるはずのない期間で作業をやってしまっている、そして残業…というわけです。

### 類似環境構築時のスケジュール短縮可能性

例えば「東西で同じシステムを構築しディザスタリカバリ環境を構成する」といったようなシステムにおいては、東の構築と西の構築で同じPlaybookを流用できるため、2回目の設計〜構築フェーズ全体を大きく短縮することができます。
もちろん従来のやり方でも同じように短縮の余地はありますが、Ansibleの場合は機械に構築作業を行わせることができるため、より大きなスケジュール短縮を見込むことが可能と考えられます。

### スケジュール短縮に関する勘違い

私の周りではたまに「Ansible使うと効率化するからスケジュール短縮できるんでしょ？」と単純に言っている人を見かけることがありました。
そのような方がいれば、勘違いなので正す必要があります。

Ansibleを使って構築が効率化するのは、使い回しの効くPlaybookを持っている場合です。
AnsibleはRoleやモジュールの組み合わせでPlaybookを作成するので、有りものを再利用しているイメージがありますが、その組み合わせを考え、PJに適合するものであることを評価するためにはどうしても時間が必要です。
Playbookの元ネタがあるなら作成に必要な期間は確かに減るとは思いますが、そのまま使えるわけではない、と認識するべきです。

Ansibleが魔法の箱ではないことはきちんと理解する必要があります。

## コスト

コストについては特に思いつきません。
Ansibleの学習コスト、新しい技術をPJに取り入れるにあたってのコンティンジェンシー予備を見積っておきましょう、くらいでしょうか(適当)。

## 品質

### Playbookの品質
Playbookの品質管理は置き去りにされがちな気がします、きちんと計画してやりましょう。放っておくと無法地帯になります。

Playbookの品質確保で行うべきことは、まずはコードレビューの文化を形成することです。
GitHubやGitLabのPull Requestなどを使うことで、簡単にコードレビューを行うプロセスを作ることができます。
併せてProtected Branchなどの機能を併用し、PJメンバーがレビューをすり抜ける可能性を排除しましょう。
また、Playbookを検証するため、テスト実行できる環境の用意も忘れずに行って下さい。今やDockerやVagrantなどでパパっと作れる時代になっています。

発展的には、Playbookの品質確保をコードレビューのみに頼るのではなく、Molecule等によるPlaybook単体テストの自動化を検討すると良いでしょう。

### 成果物の品質

テスト自動化を考慮しない場合、テストはこれまでのやり方と基本的に変わりません。
「設計-実機間のパラメータ差異が無いこと」や「狙った機能が実現できていること」を確認します。
しかしAnsibleを使う場合、これまで高頻度で行っていた「実機上のパラメータが正しく設定された」ことを確認するプロセスは必ずしも必要ではなくなることを意識してほしいです。

例えば、「一度Playbookを実行し、単体テストによってサーバ上のパラメータがすべて正しいことを確認できた」状況を想定します。
この状況においては以下が担保されているはずです。

1. Playbookの処理内容が正しい(パラメータが狙った場所に設定される)
2. Playbookに記載しているパラメータが正しい
3. 実機上設定されたパラメータが正しい

ここからパラメータの変更を行うことを考えたとき、2の正しさは毎回確認する必要はあります。しかし、3を毎回確認する必要があるかというと、そうではないと思います。
「1が正しいことは以前の単体テストにより確認済」「2は正しさを確認した」という前提では、Playbookを実行した結果が正常終了していれば、Ansibleの冪等性により3は自動的に保証されているとみなせます。
人間が手作業で変更を行う場合はヒューマンエラーの可能性があるので3のテストを毎回やるべきでしたが、Ansibleなら機械が構築するためそのようなエラーは起きないはずです。
もちろん不安だったら実機を確認しても良いですが、その作業は基本的には冗長であると考えた方が良いでしょう。
3を明示的に確認したいときは、ドライランを実行し、Playbookの内容が間違いなく実機に反映されていることを再確認するくらいで良いと思います。

## 資源

ここで言う資源とは物理的なものよりも、人間(PJメンバ)のことを指しています。

### 資源の獲得

もちろん可能であればAnsibleの知識がある人を確保した方が良いですが、そもそもAnsibleは簡単に書けるように作られているので、文字列アレルギーが無ければ習得するのは可能だと思います。
最初からAnsibleに精通している人を確保するよりも、メンバーの育成計画を立てることの方がよっぽど重要です。

### チームの育成

育成観点では、Ansibleの技術的なことだけでなく、もっと先を見据えた計画を立てるのが良いでしょう。
自動化を行うチームに求められるのは、「無駄」を認識する能力だと個人的には思います。
継続的に、既存の設計やプロセスに疑問を提起し、より効率的な手法を考案/実現できるチームを育てられれば最高ですね。

## コミュニケーション

コミュニケーションについてはAnsibleだから気をつけなければならないことは無いと思います。
もし今までGitを使ったことが無いチームであれば、レビューのやり取りはPull Request上でやろうね、とかその程度でしょうか…

## リスク

### スケジュールリスク

スケジュールについては前述の通りこれまでのやり方から大きく変わります。
特に構築フェーズのスタートが遅く、期間が短くなる点にはリスク対応計画が必要でしょう。

### 変更リスク

従来のやり方と比較して、Ansibleを使う場合は変更への対処が高速化するというプラスリスクが考えられます。
従来は変更のたびに手作業で実機上のパラメータ修正を行わなければなりませんでしたが、Ansibleでは「Playbook内のパラメータを変更して再実行」を行うだけで機械的に変更が反映されますし、パラメータの変更内容はGitを使うことににより自動的にバージョン管理されます。
プロセスがツールによって簡略化されているので、対応スピードが早まる可能性が大いにあります。

### コストリスク

Ansibleを使うことによる影響を理解できていれば、そこから発生する利点を追加のスコープとして認めてもらうことにより、売上拡大につながるといったプラスリスクが考えられるかもしれません。

## 調達

調達に関しては特に思いつきません！

## ステークホルダー

昨今注目度の高いDX(デジタルトランスフォーメーション)ですが、Ansibleはインフラ構築の世界をDXに導く重要な要素になり得ます。
この辺りに期待を持つステークホルダーを特定し、エンゲージメントを促進できれば大きな武器になるでしょう。