Terraformとは
TerraformとAnsibleを使ってGCP構築〜というタスクを任されたが、使ったことがないので概要をまとめた
概要
インフラの構築、変更、バージョン管理を安全かつ効率的に行うためのソフトウェア
設定ファイルから実行計画をたて構築を行う。 設定ファイルを変更することで、Terraformはインフラの何を変更すると適応できるのか実行計画を立てる事ができる。
Terraformは以下のものを管理する事が出来る。
- ローレベルの構成物(計算インスタンス、ストレージ、ネットワーク)
- ハイレベルの構成物(DNS エントリ、SaaS 機能、など)
- サービスをどのように構築するか、スケールするかといった知識を設定ファイルにおいてコード化(明文化)できるようにな
主な機能
- Infrastructure as Code
- version管理が出来使い回しも出来る
- 実行計画 (Execution Plans)
- 実行計画というのはTerraformに対して適用(apply)命令したときにどのように処理するかを定義したもの。 この計画があるため、Terraform がインフラを操作するとき、想定外の挙動をすることを防ぐことができる
- リソースグラフ(Resource Graph)
- 全リソースのグラフを生成できるので依存関係の無いリソースを含め、作成・変更する内容を並列化することができます。 そのため、Terraform は可能な限り効率的にインフラを構築するため、運用担当者は各々のインフラに対する依存度を確認できる
- 変更の自動化 (Change Automation)
- インフラに対して複雑な変更を適用することができる。実行計画(execution plan)とリソースグラフによって、 Terraformが何を変更して、何を実行しようとしているのか明確化できるのでhuman errorsを防ぐことができる
Terraformはchefとかansibleといったプロビジョニングとの違い
Terraformはchefやansibleと扱うレイヤーが違う。AWSを例にすると、ES2やS3の構築がTerraformで EC2上にgolangを入れたり、yum installで各種プラグインを入れたりするのがansibleなどのソフトウェアになる。 Terraformは裏でAWSなりGCPなりのAPIを読んで構成をしているだけ。なので、GUIで設定できることを設定ファイルを読み込んでモニョモニョできる。
インフラの状態を保持する
AWSなどGUIで設定したものが、どう変更されたのか知るすべが中々ない。 変更ログを逐一確認するのは現実的ではない。Terraformは状態を管理するテキストファイルで変更の差分を管理し、状態を把握している。
依存関係
例えばEC2インスタンスを作成する時に、作成APIを叩いた後、IP取得する場合とか完了するまで待たないといけないが、 IP取得して、その値を使ってモニョモニョするとかもTerraformは依存をよしなにやってくれる。
Terraformとその他ソフトウェアの比較
Terraformはリソースや事業者(provider)を抽象化する。これによって、AWS, GCP, Heroku, Akamai, オンプレ環境など、 様々な構成でも構築できる特徴がある。
実行計画、
Terraform は実行計画(execution plan)という概念で、計画フェーズと実行フェーズを分離する。 terraform planで実行計画をたて、terraform graphコマンドで処理手順の依存性を視覚化することができる。 実行フェーズでの処理内容は計画にそったものしか処理しない。
How To install
# Macの場合 brew install terraform
コマンドチートシート
# 初期化処理 terraform init # 構築計画の出力 terraform plan # 構築計画をもとに実行する (Y/n) terraform apply # 構築したサーバを削除する (Y/n) terraform destroy
.tfの記法
- .tfというファイルはterraform planやapplyで配下にあるファイルを全て実行する
- varialbleパラメータで変数を定義できる
- if, forなどを表現する記法が用意されている
- main.tf、common.tfなど共通の
- dev, prod, stgなどと環境に分けてtfを作成する場合は、それぞれでディレクトリをきってその中にtfを作る。こうする事で
.tfstate
ファイルをそれぞれで管理できる - 変数宣言も.tfで管理する場合は
variables.tf
という命名で管理するのがコミュニティで推奨されている (絶対では無い) - moduleという機能で各環境で共通する定義を
.tf
を置きmodule
ディレクトリを作成しその配下に置く事で、その場所をincludeして読み込む事ができる この時terraform get
コマンドを実行してからterraform apply
する必要がある。そして、module内の変数はincludeする.tf
から値をセットしないと使えないため注意
template Module
templateファイルを用意し、ファイル内に変数を宣言するとセットできる。
組み込み関数のfile関数から読み込み、varsディレクティブで値をセット。
読み込んだtemplateはrendered
で参照可能。
data "template_file" "deployment" { template = "${file("templates/deployment.tpl.yml")}" vars { env = "${module.common.env}" } }