RAKUS Developers Blog | ラクス エンジニアブログ

株式会社ラクスのITエンジニアによる技術ブログです。

Terraform入門と便利ツールまとめ【一気に中級者へ】

はじめまして。
顔の濃さが唯一のアイデンティティのインフラエンジニア、m_yamaです。

ラクスに入社して1年、関わっている2つのサービスでTerraformをよく触ってるので、まとめてみました。

この記事さえ読めば、きっとあなたもTerraform中級者です。
(ちょっと盛った)
(自分が中級者みたいでおこがましい)
(精進します)

目次

Terraformとは

Terraformは、いわゆるIaC(Infrastracture as Code)を体現するツールの一つで、インフラ環境をコード化できるスグレモノです。

たとえば、複数のEC2を同じ設定で起動する必要があったり、他人が作ったEC2のコピーを作る場合、「そんなとこ気付かねえよ!」みたいな、奥底で設定された値を間違えてサーバを作り直す、なんて経験をしたことがあると思います。
(EC2のパブリックIPの自動割り当てにチェックを入れずに作成してしまい、yum updateができずに泣く泣く作り直す、なんてことは良くあります)

EC2のアクションを見ていくと、「インスタンスの設定」や「セキュリティ」など、ひとつのEC2につき設定ページへのリンクが32個もありました。
全部設定する必要はないものの、全部のリソースの全ページを確認してたら日が暮れます。

Terraformでコード化していれば、コマンドぽちでポコポコ同じ設定のEC2が立ち上がるので、同じ設定が簡単に再現できます。

そのほか、以下のようなメリットがあります。

  • テスト環境・ステージング環境・本番環境など、どれか一つあればほかの環境の構築が簡単
  • 試験的に設定を変更しても、すぐに元に戻せる(性能試験がしやすい)
  • 間違えて削除してしまったリソースを、同じ設定ですぐに復元できる
  • AWSGUIがガラッと変更されて戸惑いやすいが、コード化されてれば関係ない

AWSを例に出していますが、GCPやAzure、オンプレまでいけちゃうマルチなツールです。

ざっくり理解するTerraformの全体像

Terraformは、EC2などのリソースをコード化して、「tfstate」というファイルに反映することでリソースの管理をします。
※ tfstateファイルはリソースのメタ情報など全てが記載されたファイルなので、ローカルではなくS3などに保管し、さらにバージョニングしておくと安心です。

Terraformを実行する大まかな流れは以下の通りです。(各Terraformコマンドは後述します)

  1. EC2などのリソースをコード化する(*.tfファイルを作成する)
  2. コード化したリソースが、
    • すでにある場合:TerraformimportすることでTerraform管理下に置かれる(tfstateに追記する)
    • ない場合:Terraformapplyすることでリソースを作成し、Terraform管理下に置かれる
  3. 以下、リソースを変更する場合は、コードを編集して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をコード化しましたが、あれを全部手書きするのはあまり現実的ではありません。
既存リソースをコード化するなら、GoogleGCP)が開発する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ボタンを押すだけでまとめてコードを作成できます。
(作成後のコードは載せませんが、↑で書いたようなコードが自動で作成されます)

former2.com

ブラウザに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でローカルにホストする方法もあるので、検討してみる価値はあると思います。

dev.classmethod.jp

3. profile変更が楽になる「direnv」

複数サービスのTerraformを管理していると、確認のために実行したaws cliコマンドでprofileの切り替えを忘れて、別のサービスのprofileのまま実行してしまうことがあると思います。

direnvを使うことで、ディレクトリとAWS PROFILEを紐づけられます。
これにより、ディレクトリを移動するだけでPROFILEを切り替えることができ、PROFILEの切り替え忘れを防げます。

github.com

実際に試してみます。
(※ 設定方法は上記の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


◆TECH PLAY
techplay.jp

◆connpass
rakus.connpass.com

Copyright © RAKUS Co., Ltd. All rights reserved.