はじめまして。
顔の濃さが唯一のアイデンティティのインフラエンジニア、m_yamaです。
ラクスに入社して1年、関わっている2つのサービスでTerraformをよく触ってるので、まとめてみました。
この記事さえ読めば、きっとあなたもTerraform中級者です。
(ちょっと盛った)
(自分が中級者みたいでおこがましい)
(精進します)
目次
Terraformとは
Terraformは、いわゆるIaC(Infrastracture as Code)を体現するツールの一つで、インフラ環境をコード化できるスグレモノです。
たとえば、複数のEC2を同じ設定で起動する必要があったり、他人が作ったEC2のコピーを作る場合、「そんなとこ気付かねえよ!」みたいな、奥底で設定された値を間違えてサーバを作り直す、なんて経験をしたことがあると思います。
(EC2のパブリックIPの自動割り当てにチェックを入れずに作成してしまい、yum updateができずに泣く泣く作り直す、なんてことは良くあります)
EC2のアクションを見ていくと、「インスタンスの設定」や「セキュリティ」など、ひとつのEC2につき設定ページへのリンクが32個もありました。
全部設定する必要はないものの、全部のリソースの全ページを確認してたら日が暮れます。
Terraformでコード化していれば、コマンドぽちでポコポコ同じ設定のEC2が立ち上がるので、同じ設定が簡単に再現できます。
そのほか、以下のようなメリットがあります。
- テスト環境・ステージング環境・本番環境など、どれか一つあればほかの環境の構築が簡単
- 試験的に設定を変更しても、すぐに元に戻せる(性能試験がしやすい)
- 間違えて削除してしまったリソースを、同じ設定ですぐに復元できる
- AWSはGUIがガラッと変更されて戸惑いやすいが、コード化されてれば関係ない
※ AWSを例に出していますが、GCPやAzure、オンプレまでいけちゃうマルチなツールです。
ざっくり理解するTerraformの全体像
Terraformは、EC2などのリソースをコード化して、「tfstate」というファイルに反映することでリソースの管理をします。
※ tfstateファイルはリソースのメタ情報など全てが記載されたファイルなので、ローカルではなくS3などに保管し、さらにバージョニングしておくと安心です。
Terraformを実行する大まかな流れは以下の通りです。(各Terraformコマンドは後述します)
- EC2などのリソースをコード化する(*.tfファイルを作成する)
- コード化したリソースが、
- すでにある場合:TerraformimportすることでTerraform管理下に置かれる(tfstateに追記する)
- ない場合:Terraformapplyすることでリソースを作成し、Terraform管理下に置かれる
- 以下、リソースを変更する場合は、コードを編集してTerraformplanで確認し、Terraformapplyで反映する(+ tfstateファイルの更新)
Terraformの参考コード(EC2編)
参考までに、EC2のTerraformコードを書いてみました。
例えばこの場合、以下のようなメリットがあります。
- amiを明記することでバージョンを統一でき、バージョン違いによる微妙な挙動の違いを防げる
- stagingなど別環境を作る際、PrivateIPのホスト部を統一しやすい(IPから中身がイメージしやすくなる)
- EC2やEBSで忘れがちなタグのNameを設定できる
コード化することで、以下のように「あのサーバの設定なんだっけ、どこで設定してたっけ」のような無駄な時間がなくなり、リソースの管理や開発の効率が高まります。
resource "aws_instance" "test-server-01-example-co-jp" { ami = "ami-xxxxxx" availability_zone = "ap-northeast-1a" ebs_optimized = true instance_type = "t3.small" monitoring = true key_name = "key-pair-name" subnet_id = aws_subnet.id vpc_security_group_ids = [aws_security_group.test-server-sg.id] private_ip = "10.10.1.5" root_block_device { volume_type = "gp3" volume_size = 100 delete_on_termination = true tags = { Name = "test-server-01.example.co.jp" } } tags = { "Name" = "test-server-01.example.co.jp" } }
リソースをコード化するメリットって?
リソースをコード化してgitなどでバージョン管理すれば、
- レビューで認識齟齬がないことを確認しやすい
- 同一リソース・別環境の複製(test、staging環境など)が容易
- コミットログから過去の変更時期や意図を確認しやすい
- ブラウザでの操作のように、設定変更ページを探す必要がない
- 一時的に手動で変更した設定の戻し忘れに気付きやすい(手動変更するなという話ですが)
など、メリットがたくさんあります。
AnsibleやChef、Puppetとの違い
IaCの文脈で同列に語られがちなAnsible・Chef・Puppetは、サーバの「中」の設定をコード化するツールになります。
たとえば、OSユーザーの追加だったり失敗すると怖いsudoersとかだったり、Nginxや各種ミドルウェアなどのインストールなどがコード化できます。
Terraformは、サーバそのものや、ネットワーク、ストレージなどのサーバの「外」をコード化するツールなので、TerraformとAnsible等を上手く使い分けることで、環境構築や既存環境の改修がとても楽になります。
※ Terraformでも、起動時のテンプレートを設定できたりしますが、Ansible等の方が柔軟性が高く使い勝手がいいです。餅は餅屋。
Terraformの使い方
公式サイトからダウンロードして、GetStartedするだけ。
yum install(apt install)したことがあるなら一瞬です。
※ 結構バージョンアップが早く、それによる破壊的な変更があったりするので、バージョンや更新情報に気を使う必要はあります。
よく使う、基本的なTerraformコマンドの一部を紹介します。
基本的にはこの2つ「plan」「apply」
一番使うコマンドは、きっと terraform plan
だと思います。
コードを編集して、意図した変更になるかを確認するときに使います。
plan
で確認した後、実際反映するのは terraform apply
コマンドになります。
applyコマンドで 意図せぬ変更をしてしまうと戻せない(作り直す必要がある)場合もあるので、必ずterraform planコマンドを打って確認する必要があります。
既存リソースをTerraform管理する「import」
既存のリソースをTerraformで管理する場合に必要になるのが、 terraform import
コマンドです。
たとえば、さきほど紹介したコード化したEC2が存在していて、Terraform管理されていない場合、そのままapplyコマンドを実行すると、その設定のEC2を新規作成しようとします。
importコマンドを実行することでコードとリソースが紐づき、Terraform管理できます。
$ terraform import aws_instance.test-server-01-example-co-jp i-xxxxxxxxxx(インスタンスID)
なにをTerraform管理しているかを確認する「state list」
管理するリソースが増えてくると、今Terraformで何を管理しているのかを一覧で見たいタイミングも出てくると思います。
そういったときに、terraform state list
コマンドを使うことで一覧出力できます。
grepで特定のタイプのリソースに絞ったり、全体を俯瞰するときに便利です。
$ terraform state list aws_instance.test-server-01-example-co-jp aws_security_group_rule.test-server-sg aws_vpc.test-01-vpc ... ...
Terraformの3大便利ツール
Terraformを使い始めて1年ぐらいたち、いろいろ便利なツールも見つけたのでまとめて紹介します。
1. 既存環境を楽にTerraform管理する「Terraformer」
先ほどEC2をコード化しましたが、あれを全部手書きするのはあまり現実的ではありません。
既存リソースをコード化するなら、Google(GCP)が開発するTerraformerというツールを使うのが便利です。
以下のようにコマンドを実行すると、既存リソースからコードを作成してくれるので、ほとんど自分でコードを書く必要がありません。
$ terraformer import aws --resources=ec2_instance ... # いろいろ作成される $ ls generated/aws/ec2_instance/ instance.tf outputs.tf provider.tf terraform.tfstate $ cd generated/aws/ec2_instance/ $ terraform init $ terraform plan
※ ↑のように、作成されたディレクトリに移動してTerraform planを実行すると、コード通りのEC2を作成しようとします。
先述した「terraform import」でコードとリソースを紐づけることで、既存のリソースをTerraform管理できます。
2. GUIでTerraformコードを生成できる「former2」
Terraformerはcliでの操作なので、慣れない人は使いにくいかもしれません。
そういう方には、GUIで既存リソースをコード化できる「former2」がおすすめです。
以下の画像のようにリソースを選択でき、Generateボタンを押すだけでまとめてコードを作成できます。
(作成後のコードは載せませんが、↑で書いたようなコードが自動で作成されます)
ブラウザにcredentialsを登録することで、ボタンポチポチで欲しいリソースをコード化できます。
安全性が気になるところですが、AWS公式ブログでも以下のように紹介されています。
Former2 is designed never to send these credentials to an external server that isn’t an AWS API endpoint.
引用元:Accelerate infrastructure as code development with open source Former2
ブラウザにcredentialsを登録することに抵抗がある方(ほとんどの人はあると思いますが)は、docker-composeでローカルにホストする方法もあるので、検討してみる価値はあると思います。
3. profile変更が楽になる「direnv」
複数サービスのTerraformを管理していると、確認のために実行したaws cliコマンドでprofileの切り替えを忘れて、別のサービスのprofileのまま実行してしまうことがあると思います。
direnvを使うことで、ディレクトリとAWS PROFILEを紐づけられます。
これにより、ディレクトリを移動するだけでPROFILEを切り替えることができ、PROFILEの切り替え忘れを防げます。
実際に試してみます。
(※ 設定方法は上記のgithubを参照してください)
たとえば、以下のように、複数サービスを管理しているとします。
works ├── serviceA │ └── .envrc └── serviceB ├── .envrc └── .envrc_prod
以下は実際に操作した画面になります。
※ 前提: direnvを使って、各サービスのディレクトリで.envrcを作成していること
① serviceAディレクトリに移動すると、serviceA/.envrcが自動で読み込まれて、AWS_PROFILE=serviceA-test
がセットされます。
② そこからserviceBに移動すると、serviceB/.envrcが読み込まれ、AWS_PROFILE=serviceB-test
がセットされます。
③ また、serviceB/.envrc_prodのような本番用のPROFILEファイルを作成し、sourceで明示的に読み込めば、本番用のAWS_PROFILE=serviceB-prod
に切り替わります。
基本的にはtest用PROFILE、必要なときのみ本番用PROFILEを読み込む、といった使い方ができて便利です。
(promptが設定されてると、本番系(-prod
など)のPROFILE名だと色が変わって、すぐにわかるのもありがたいです)
④ direnvで設定されていないディレクトリに移動すると、環境変数がunsetされるのも安心です。
まとめ
Terraformと便利ツールについてまとめてみました。
Terraformを使いこなせれば、リソースの管理がとても楽になるので、まだの方はぜひ試してみてください。
もっと体系的に学びたい、という場合は、以下の書籍がおすすめです。
実践Terraform AWSにおけるシステム設計とベストプラクティス (技術の泉シリーズ(NextPublishing)) | 野村 友規 | 工学 | Kindleストア | Amazon
エンジニア中途採用サイト
ラクスでは、エンジニア・デザイナーの中途採用を積極的に行っております!
ご興味ありましたら是非ご確認をお願いします。
https://career-recruit.rakus.co.jp/career_engineer/カジュアル面談お申込みフォーム
どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。
以下フォームよりお申込みください。
rakus.hubspotpagebuilder.comラクスDevelopers登録フォーム
https://career-recruit.rakus.co.jp/career_engineer/form_rakusdev/イベント情報
会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください!
◆TECH PLAY
techplay.jp
◆connpass
rakus.connpass.com