はじめに
SREチームでTerraformを利用していくにあたって、周囲の理解が必要なことがありますよね。
この記事の背景として、社内に理解者を増やして、ツールの導入をスムーズにしたいという想いがあります。
ということで、社内のサーバーサイドエンジニアのようなインフラ系専門エンジニアではない人向けに社内Terraform共有会を開催する目的で書いています。
目次
Infrastructure as Codeとは何か
What
オライリー・ジャパンから出版されている『Infrastructure as Code』より引用するとIaCは以下のような定義となる。
Infrastructure as Codeは、ソフトウェア開発のプラクティスをインフラのオートメーションに活かすアプローチだ。1
Why
どうしてInfrastructure as Codeを行うかというと以下のような効果を期待するためだ。
● ITインフラが変化の障害や制約になるのではなく、変化を支えて実現すること。
● システム変更がユーザーやITスタッフのストレスや大事件ではなく、日常作業になること。
● ITスタッフが、日常的反復的なタスクではなく、彼らの能力を活かした価値のある仕事のために時間を使うこと。
● ユーザーがITスタッフに頼るのではなく、自分で必要なリソースを定義、プロビジョニング、管理できるようになること。
● 失敗を完全に予防できるという前提に立つのではなく、失敗が発生しても簡単かつスピーディに回復できるようになること。
● コストがかかりリスキーな「ビッグバン」プロジェクトではなく、継続的な作業により改善、改良を実現すること。
● 会議やドキュメントでソリューションを論ずることではなく、実装、テスト、計測を通じてソリューションの効果が証明されるようになること。2
How
具体的にどのようなことをしていくかというと、ソフトウェア開発で行ってきたバージョン管理、自動テストライブラリ、デプロイのオーケストレーションといったことをインフラ管理にも応用していく。
Terraformの説明
Infrastructure as Codeツール分類
Terraformは『Infrastructure as Code』で紹介されるツール分類より引用すると以下の4つ3の中でインフラストラクチャ定義ツールに該当する。
- ダイナミックインフラストラクチャプラットフォーム(AWS、GCP、Azure等)
- インフラストラクチャ定義ツール(Terraform、CloudFormation等)
- サーバー構成ツール(Ansible、Chef、Puppet等)
- インフラストラクチャサービス(Datadog、NewRelic、CircleCI等)
Terraformとは
- HashiCorpが作成したオープンソースの構成管理ツール。
- 例えばクラウドベンダー(AWS、GCP、Azure)のクラウドリソースのインフラ構成を宣言的に定義できるところが特徴。構成手順を書くのではなく、構成定義を書くという形になる。(Ansibleとの違い)
- Providersには、物理マシン、VM、ネットワークスイッチ、コンテナ、監視ツール、データベース等の色々な選択肢がある。
- ファイルはHashiCorp Configuration Language (HCL) で記述される。
Terraformの仕組み
Terraformはtfstate
と呼ばれるファイルとHCLの差分を確認して、必要な部分だけに変更をかけてくれる。
tfstate
ファイルはTerraformを一度でもapplyすれば作成され、現在の状態を記録してくれる。
図はTakahisa Iwamoto氏の資料を見るとイメージが付きやすいのでおすすめ。
Terraformのメリット
- HCLで宣言的にリソース定義ができ、リソース作成順序を自動的に判断してくれるため、リソース変更作業者のケアレスミスを回避できる。
- クラウドベンダーを選ばずTerraformでソースコード管理することができる。
- 繰り返し行われるインフラ構築作業トイルを巻き取ってくれる可能性がある。
Terraformのデメリット
- HCLの記法や各構築対象サービスのお作法を学ぶ必要がある。
- ツール自体開発が活発に行われている最中であるため、新しい記法やお作法の情報を追従することが必要になる。
- 破壊的変更を伴う作業ができてしまうので対策が必要になる。
Terraformを安全に使うためには
Terraformではライフサイクルによる削除抑止定義を行うことができる
lifecycle{
prevent_destroy=true
}
このように削除されたくないリソースに関しては設定を入れると削除できなくなります。
ただし、この設定を入れても絶対安全というわけではなく、リソース定義自体を消してapplyすれば削除されてしまう。
apply時は実行者によるチェックも重要になってくる。
Terraformハンズオン
AWSのセットアップ
AWSのIAMユーザーを作成
-
AWSマネジメントコンソールのIAMに移動
-
ユーザー → ユーザーを追加の順にクリック
-
ユーザー名を入力
-
タグは追加せず → 次のステップ:確認
-
ユーザーの作成
AWS CLI
AWS CLIをpip3からインストールします。インストールしたらバージョンを確認してみます。
$ pip3 install awscli --upgrade
# 確認
$ aws --version
クレデンシャルを環境変数として設定
AWSマネジメントコンソールからアクセスキーID、シークレットアクセスキーをコピーしてexportする。
$ export AWS_ACCESS_KEY_ID=XXXXXXXXXXXXXXXXXXXX
$ export AWS_SECRET_ACCESS_KEY=XXXXXXXXXX/XXXXXXXXXX/XXXXXXXXXX
$ export AWS_DEFAULT_REGION=ap-northeast-1
Terraformのセットアップ
そしていよいよTerraformのインストールを行うが、今後のバージョン管理も考えてtfenvでのインストールをここでは記載しておく。
tfenvのインストール
tfenvはTerraformのバージョンマネージャー。バージョンを上げたり下げたりしたい場面で非常に有効になるのでこちらでのインストールをお勧めする。
# Macの場合
$ brew install tfenv
# 確認
$ tfenv --version
tfenv 1.0.1
# それ以外の場合
$ git clone https://github.com/tfutils/tfenv.git ~/.tfenv
$ echo 'export PATH="$HOME/.tfenv/bin:$PATH"' >> ~/.bash_profile
$ source ~/.bash_profile
# 確認
$ tfenv --version
tfenv 1.0.1
※READMEではシンボリックリンクによるPATH設定の方法もあるので好みで選択できる。
tfenvの使い方
tfenv list-remote
インストールできるバージョンの一覧を取得する。
$ tfenv list-remote
0.12.12
0.12.11
0.12.10
0.12.9
...
tfenv install
対象のバージョンをインストールする。
$ tfenv install 0.12.12
tfenv list
インストール済みのバージョンを確認する。
$ tfenv list
* 0.12.12 (set by /usr/local/Cellar/tfenv/1.0.1/version)
0.12.5
tfenv use
複数バージョンを切り替える場合はuse
を使う。
$ tfenv use 0.12.5
AWS EC2を作成してみる
作業ディレクトリの作成
Terraform作業用にディレクトリを用意する。
$ mkdir terraform_test
$ cd terraform_test
$ vim main.tf
main.tfには以下を記載する。
resource "aws_instance" "test" {
ami = "ami-04b9e92b5572fa0d1"
instance_type = "t3.micro"
}
terraform init
コードを記載したら、main.tfがあるディレクトリでterraform init
を実行して、バイナリファイルをダウンロードする。
$ terraform init
Initializing the backend...
Terraform has been successfully initialized!
$ terraform plan
terraform plan
で実行計画を出力させて、どのような変更が行われるか確認する。
$ terraform plan
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# aws_instance.test will be created
+ resource "aws_instance" "test" {
+ ami = "ami-04b9e92b5572fa0d1"
+ arn = (known after apply)
+ associate_public_ip_address = (known after apply)
+ availability_zone = (known after apply)
+ cpu_core_count = (known after apply)
+ cpu_threads_per_core = (known after apply)
+ get_password_data = false
+ host_id = (known after apply)
+ id = (known after apply)
+ instance_state = (known after apply)
+ instance_type = "t3.micro"
......}
Plan: 1 to add, 0 to change, 0 to destroy.
+マークがでているところが重要で、新規にリソースを作成するという意味になる。
terraform apply
terraform apply
で実行計画からでていた変更を実際に行わせる。
$ terraform apply
......
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value:
ここでyes
を入力すると実行される。
aws_instance.test: Creating...
aws_instance.test: Still creating... [10s elapsed]
aws_instance.test: Creation complete after 18s [id=i-095131324a66cb153]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
AWSマネジメントコンソールでEC2インスタンスができていることを確認する。
AWS EC2の情報を更新してみる
EC2の作成に成功したら、変更をしてみる。
先程作成したmain.tfを以下に書き換える。
resource "aws_instance" "test" {
ami = "ami-04b9e92b5572fa0d1"
instance_type = "t3.micro"
tags = {
Name = "test"
}
}
コードを修正したらterraform apply
を実行する。
+
マークから~
マークに変化してaws_instance.test will be updated in-place
が表示される。
これは既存のリソースの設定を変更する
という意味になる。
AWSマネジメントコンソールでも、Nameタグの追加が確認できる。
AWS EC2を再作成してみる
Nginxをインストールするため、以下のようにmain.tfを変更してapplyする。
resource "aws_instance" "test" {
ami = "ami-04b9e92b5572fa0d1"
instance_type = "t3.micro"
user_data = <<EOF
#!/bin/bash
apt-get install nginx
systemctl start nginx.service
EOF
}
今度は-/+
マークがつきaws_instance.test must be replaced
というメッセージが表示される。
これは既存のリソースを削除して新しいリソースを作成する
という意味になる。
リソースの削除を伴う作業
になるので、本当に実行していいのか確認する必要がある。
AWS EC2を削除する
terraform destroy
で作成したリソースを削除できる。
-
マークがつきaws_instance.test will be destroyed
というメッセージが表示される。
これは既存のリソースを削除する
という意味になる。
参考
今回は触りしか書かなかったので、もしより詳しくTerraformを知りたい場合はこちらを購入することをオススメする。
野村 友規. 実践Terraform AWSにおけるシステム設計とベストプラクティス
-
Kief Morris(2017年03月)『Infrastructure as Code』(宮下 剛輔 監訳、長尾 高弘 訳) オライリー・ジャパン 「1章課題と原則 1.2 Infrastructure as Codeとは何か」 より引用 ↩
-
Kief Morris(2017年03月)『Infrastructure as Code』(宮下 剛輔 監訳、長尾 高弘 訳) オライリー・ジャパン 「1章課題と原則 1.2.1 Infrastructure as Codeの目標」 より引用 ↩
-
Kief Morris(2017年03月)『Infrastructure as Code』(宮下 剛輔 監訳、長尾 高弘 訳) オライリー・ジャパン 「1章課題と原則 1.8 この後の章について」 より引用 ↩