TerraformでAWSのIaCを始める・始めたばかりの人へ #devio2024 #cm_odyssey

TerraformでAWSのIaCを始める・始めたばかりの人へ #devio2024 #cm_odyssey

Clock Icon2024.08.01

DevelopersIO 2024 OSAKAにて、「TerraformでAWSのIaCを始める・始めたばかりの人へ」という内容で登壇いたしました。お越しいただいた皆様、ありがとうございました!

本ブログはその内容をブログ向けに改変したものになります。

ゴール

  • Terraformを使ったこと無い方には、Terraformの使い方や魅力を知っていただき、「使ってみよう」と思っていただくこと
  • すでにTerraformをお使いの方には、より良い使い方を持ち帰っていただくこと
  • ※ タイトルに「AWS」とありますが、あまりAWS関係ありません。AWSを使われない方でも楽しんでいただける内容になっているかなと思います。

自己紹介

selfintro.png

かずえと申します。HashiCorp Ambassadorsという制度があります。HashiCorpというのはTerraformの開発元の会社なのですが、そのHashiCorpの製品のコミュニティに貢献した人を表彰する制度です。そちらに2年連続選出いただいております。

最近気をつけているのは「Terraform」のアクセントです。特にアクセント無く発音していたのですが、英語圏ではアクセントはアタマの「テ」の部分に来るというのを最近知りました。ですので、そのアクセントで発音するように気をつけています。ですが正直まだ全然矯正できていません。

Terraformとは

  • IaC (Infrastructure as Code) ツール。インフラリソースやクラウドリソースなどをコード化できる
  • HashiCorp社が開発元。HashiCorp社とコミュニティで開発・メンテナンスを行なっている

IaCのメリット

「なぜ IaCをするのか?」ということです。

  • バージョン管理ができるので、インフラの変更履歴を追うことができる。
  • コードレビューができる。
  • 再利用、横展開がし易い。

ただこれらのメリットは他のIaCツール、例えばCloudFormationなどでも享受できるメリットです。なぜTerraformを使うのか、Terraformの良い点について、説明します。

Terraformの魅力1: シンプル

HCL

TerraformはHCL=HashiCorp Configuration Language という書式でコードを書きます。このHCLが非常に直感的で読みやすいです。プログラムを書いたこと無いよ、という方でもとっつきやすいと思います。

柔軟

書き方の自由度が高いです。Terraformは前述のHCLという書式で、.tfという拡張子のファイルにコードを書いていくのですが、その際、ファイルの分割単位は好きにして良いです。1つのファイルに全部の設定を書いてもいいですし、同じディレクトリ上であれば自分の好きな単位、読みやすい単位でファイル分割して書いても良いです。

また、記載順も好きにできます。リソースAとリソースBについての記述があったとして、この記載順が逆になっても問題ないです。Terraformはリソース間の依存関係を把握し、正しい順序で処理してくれます。

※ ファイル分割単位、記載順ともにベスプラはあります。 Style Guide - Configuration Language | Terraform | HashiCorp Developer

コマンドが簡単

コマンドも簡単です。最低限terraform initterraform applyだけ使えればIaCできます。

Terraformの魅力2: 活躍域が広い

range.png

TerraformはAWS専用IaCツールではないです。GoogleCloudなど他のクラウドサービスでも使えますし、KubernetesリソースやVM、SaaSの設定などにも使えます。ですので今後AWSを使わない現場や会社に行ったとしても、お持ちのTerraformのスキルを活かすことができます。Terraformのスキルを身につけるというのはキャリアにとってひとつとても良い選択肢なのではと思います。

Terraformの魅力3: 情報の豊富さ

まず公式ドキュメントが充実しています。各種文法やコマンドなどのドキュメントページがしっかり整備されています。チュートリアルもたくさんあります。(ただ、残念ながら英語版しかありません)

また、Terraformは約10年前に誕生した、成熟したツールです。たくさんの使用実績があり、すでに様々な情報がネット上にあります。何か問題が起きても、ググればすぐにその解決策が見つかるはずです。

Terraformの使い方

ざっくりTerraformの使い方をお伝えします。

1. インストール

TerraformのCLIをローカル端末にインストールする必要があります。以下を参照ください。

2. コードを書く

以下は、バケット名を指定したS3バケットを一つ作成するコードです。

バケットについてのコードは最下段の3行です。他はTerraform全体についての設定を書いています。

terraform {
  required_version = "= 1.9.1"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.58.0"
    }    
  }
}

provider "aws" {
  region = "ap-northeast-1"
}

resource "aws_s3_bucket" "test" {
  bucket = "devio-osaka-2024"
}

3. terraform init コマンド

いわゆる初期化処理を行うコマンドです。こちらは基本的に最初に1回実行すればOKです。

4. (クレデンシャル取得)

このあたりでAWSのクレデンシャルを取得して、リソースを作成できる権限を持っておいてください。

5. terraform apply コマンド

このコマンドを実行すると、「こういう処理を行いますが良いですか?」といった感じでdiffが表示されます。今回の例ですとS3バケットを作成するコードなので、S3バケットを作るというdiffが表示されます。そのバケットの設定値を詳細に確認することもできます。指定した通りのバケット名になることがわかりますね。

diff.png

6. type "yes"

上記diffの下に

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とタイプすると、前述の処理(ここではバケット作成)が実行されて、プロビジョニング完了です。

今後は、「コード書き足す」 → 「terraform applyでdiff確認」 → 「type "yes"」の流れを繰り返すことで、IaCを進めていくことができます。

Terraformの仕組み

ここからはTerraformの仕組みについて軽く解説します。

Terraformとは(ざっくり)

ざっくりいうとTerraformとは、作りたいリソース(例えばAWS)の「APIをいい感じに実行してくれる」IaCツールです。

zakkuri.png

図にするとこうです。

API.png

開発者がterraform applyでリソース作成をTerraformに指示すると、Terraformがあなたの代わりにAWSのAPIを実行してくれて、リソースが作成されます。

API

ご存知かもしれませんが、AWSのほとんどのアクションはAPI化されています。以下はS3のCreateBucketのAPIのドキュメントページです。

createbucket.png

先程「Terraformの使い方」の項にてS3バケットを一つ作るTerraformコードを作ってterraform applyしましたが、あのとき裏でTerraformはこのAPIを実行しています。

ただ、先程私は「APIをいい感じに実行してくれる」と言いました。この「APIをいい感じに実行する」というのはどういうことでしょうか?説明していきます。

「APIをいい感じに実行する」とは

API.png

先程の図の再掲です。これをより詳細に説明すると以下の図になります。

state.png

開発者がterraform applyするところまでは同じです。そのあとStateファイルという新キャラが登場していて、Terraformがそれを読みに行っています。まずはStateファイルを説明しましょう。

Stateファイル

その名の通りですが、Terraformで管理しているリソースの「現在の状態」が格納されているファイルです。

デフォルトだとTerraformが実行されるのと同じディレクトリに、terraform.tfstateという名前で作成されます。

設定次第ではS3バケット上に置くなどできます。ローカルにあると他の開発者がアクセスできなくて不便なので、大抵のプロジェクトではS3バケット上に置くことが多いです。

リソースの現在の状態が確認されているとはどういうことなのか、実際にStateファイルの中を覗いて確認してみましょう。

resource "aws_s3_bucket" "test" {
  bucket = "devio-osaka-2024"
}

先ほど、上記のようなS3バケットを一つ作るTerraformコードを作成しました。これをterraform applyしてバケット作成すると、Stateファイルの中身は以下のようになります。

content.png

コード内容と同じように、 aws_s3_bucketタイプのtestという名前のリソースについての情報がありますね。で、下の方にそのバケットの設定値がズラッと記載されています。コード内で指定したバケット名についてもありますね。

再び 「APIをいい感じに実行する」とは

もう一度図に戻ります。

state.png

開発者がterraform applyを実行すると、Terraformはまず今ご説明したStateファイルを読みに行きます(2.readの部分)。このStateファイルの中には各リソースのIDも記載されています。S3バケットの場合はバケット名がIDになりますね。そのIDを使って参照系のAPIを実行します(3. API (READ))。getなんたらとかdescribeなんとかとかのAPIですね。それによってそのリソースの現状の設定を確認します。

もし現状の設定がStateファイル記載内容と異なっていた場合、例えばだれかがTerraform外で、マネジメントコンソールで設定変更したとかですね、Terraformはその変更もStateファイルに反映します(4. update)。

その後ですね、TerraformはコードとStateファイル、つまりリソースの現状とのdiffを表示します(5. diff between code and state)。

最後に、その差分を埋めるべく、適切な更新系のAPIを実行します(6. API (CREATE/UPDATE/DELETE or nothing))。

「6. API (CREATE/UPDATE/DELETE or nothing)」のところ、重要なので繰り返します。Terraformは、リソースの現状とコードの間の差分を埋めるために、適宜適切なAPI=Create、Update、Delete系のAPIを実行する、あるいは必要ないときは実行しない、というのをいい感じに使い分けてくれます。これがTerraformの仕組みです。

あらためて、「APIをいい感じに実行する」を言い換えると、以下となります。「APIを冪等的に実行する」です。

bekitou.png

ここからTerraform Tips集

Terraformの仕組み、なんとなくご理解いただけましたでしょうか。ここからはすでにTerraformを使われている方向けにいくつかTipsをご紹介します。

TerraformのVersionを簡単に切り替える

different-version.png
プロジェクトAでは version1.9.3のTerraformを使っているけど、プロジェクトBではまだ1.7.0みたいな状況のことです。

実はTerraform自体にはVersionを切り替える仕組みがありません。インストールし直すしかないです。そんな事やってられないので、以下ツールを是非お使いください。

tfenv

このtfenvというツールをインストールしたうえで、Terraformを実行するディレクトリ上に.terraform-version ファイルを作成し、その中に min-required と書いておきます。

それだけで、先程ご説明した terraform init時に、コード内に書かれたVersionの設定を読んで、それに合うVersionのTerraformをインストールして使ってくれるようになります。

tfenv.png

これによって、各開発者はローカルに今入っているTerraformのVersionを気にしなくて良くなる(勝手に切り替えてくれるから)ので、非常に快適です。

詳細は以下をご参照ください。

クレデンシャルを簡単に切り替える

different-cred.png

環境というのは dev/stg/prodみたいなやつのことです。

このケースは普通にありえるというか、むしろAWSのベストプラクティスとしては環境やワークロード毎にAWSアカウントを分離することを推奨しています。

AWSアカウントが違うということは、つまり使用するAWSのクレデンシャルを切り替えないといけないということですね。

かつ、仮に間違ったクレデンシャルを使ってTerraformを実行してしまうと、要らないリソースを作ってしまったりだとか、プロビジョニング済のリソースを削除してしまったりと言った大事故に繋がる恐れがあります。絶対にミスりたくないですね。ですので、次のツールを使ってみてください。

direnv

こちらは、特定のディレクトリに移動した際に実行されるスクリプトを書ける、というツールです。

そして大抵の場合、Terraformを実行するディレクトリとそこで使うクレデンシャル、つまりはプロビジョニング先のAWSアカウントって1対1の関係で紐づいていると思います。ですので、そのdirenvスクリプトの中で適切なAWSアカウントのIAMロールに assume roleするような処理を実行するようにすれば、クレデンシャル間違いは発生しなくなります。また、ディレクトリ移動だけで自動でクレデンシャル取得が実行されるので非常に楽です。

direnv.png

詳細は以下をご参照ください。

Terraformを高速化する

parallel.png
前述の図の3番と6番のAPIを実行する部分、この部分はデフォルトでは並列度10で実行されます。ですが設定次第でこの並列度を上げることができます。

parallelism オプション

parallel-op.png

terraform planterraform applyにオプション指定することで実現できます。または代わりに環境変数で指定することも可能です。

実際に弊社内で以下のように劇的に実行時間を改善できた事がありました。

nyama2.png

これは確か400リソースくらい管理しているTerraformコードだったので、同じような結果をみなさんが得ることはなかなか難しいかもしれません。ですが、terraform planterraform applyコマンドは日常的に使うコマンドですので、都度の実行時間が少しでも短縮できればチリツモで効いてくるのではないかと思います。私はdirenvの中で環境変数を指定しています。

HCP Terraform(旧名:Terraform Cloud)を使う

HCP TerraformはTerraformのSaaSです。HashiCorp社が提供しています。

Terraformを利用する上で便利な様々な機能がすぐに使える、といったSaaSです。

そしてこの便利な機能にTerraform利用を寄せていくことで、ゆくゆくはTerraformの利用方法を会社内で標準化するのにも役立ちます。

今回はみっつ、HCP Terraformの良い点をご紹介します。

メリット1: Terraform実行環境を統一できる

「Terraformの使い方」の項でご紹介した通り、Terraformは基本的にはローカル端末にてCLIをインストールして、ローカルから実行するツールです。

ですがローカルから実行することによって、次のような問題が発生する場合があります。

ex-env.png

まず、各開発者にAWSの強い権限を付与する必要があります。Terraformで作成するAWSリソースがプロジェクト開始時に厳格に決まっていることなんてほぼ無いので、大体の場合余裕のある強めの権限、AdministratorAccess権限などを付与することが多いかと思います。これがセキュリティリスクにもなりますし、また開発者の異動が激しい場合は設定変更も手間になります。

また、ローカル環境差異による問題というのも稀に発生します。Windows端末とMac端末ではTerraformの実行結果がやや異なる、みたいなケースです。

同じことがローカル環境とCDパイプライン間でも発生し得ります。ローカルでは動くけどCDパイプラインだとうまく動かない…みたいなケースですね。

HCP Terraformの場合、ローカルからコマンドを実行しても、実行環境はHCP Terraform上(のVM)にすることができます。どこからコマンド実行しても同じ実行環境上で実行されますので、前述のような環境差異による問題が発生しなくなります。また、各開発者にAWSの強権限を付与する必要もなくなります。

メリット2: CDパイプラインをすぐに作れる

これが一番大きいメリットなのではと思います。Gitリポジトリと連携したTerraformのCDパイプラインがすぐに作れます。

HCPTerraformのWeb UIとGitHub上でそれぞれいくつか設定ポチポチするだけで、以下のようなパイプラインが作成できます。

addtag.png

git pushしただけで自動でterraform planが実行され、結果のdiffがWeb UIから確認できます。この例だと EC2インスタンスを1台作成するというdiffが生成されています。緑の「+」の部分をクリックすれば、EC2インスタンスの設定も細かく確認できます。

そしてapplyはペンディング状態になっています。最下部にある青い「Confirm & apply」ボタン押下でterraform applyを開始できます。つまりは承認フェーズ付きのCDパイプラインを簡単に作成できるというわけです。

別に他のサービスを使ってCDパイプラインを作ることもできますが、TerraformのCDパイプラインについてはHCP Terraformが一番カンタンに、かつ質の良いものが作成できるのではと思います。

メリット3: Stateファイルを簡単に安全に管理できる

先ほどStateファイルの説明の際に、S3バケット上に置くことができると説明しました。

Stateファイルにはリソースの情報が色々と記録されています。例えばRDSをTerraformで作成した場合、そのパスワードもStateファイルには記録されています。ですので厳重に扱わないといけないファイルです。

state-prob.png

S3バケット上に置くことができますが、そのS3バケットの設定を色々と行わないといけませんし、そのバケットのIaCをどうやってやるかも考えないといけません。(Terraformコード内でプロビジョニングすることもできますが、そうすると色々面倒なことが発生するので、できればTerraform外で作成した方がよいです。)

state-hcp.png

HCP Terraformの場合、S3バケットを用意、設定する必要はありません。HCP Terraform側で管理してくれます。なおかつS3だと自分で設定が必要だったバージョニング、暗号化などもデフォルトで組み込まれています。アクセス制限も細かく設定可能です。

さらに、Stateの変更履歴をWeb UIから確認することができます。以下の例だと履歴が3件あることがわかります。

history.png

さらに、各履歴の詳細も確認でき、具体的にどのような変更があったのか把握可能です。

history-detail.png

このページ上には紐づくgit コミットのリンクもあります。

このStateファイルについての詳細は以下ブログをご参照ください。

価格

他にもHCP Terraformは便利機能が色々あるのですが、気になるのはお値段だとおもいます。こちら、無料で始められます。

price.png

月あたり 500リソースまでならHCP Terraformで管理しても無料でご利用いただけます。

500リソースって結構多いので、最初のうちは全然無料利用枠内で収まるのではないかなと思います。ただし有償版やさらに一つ上のプラン(HCP Plus)でないと利用できない機能というものもありますので、その点はご注意ください。

そして、HCP Terraformは弊社クラスメソッド経由でもご契約いただけます。
弊社経由でご契約いただきますと、AWS利用費とHCP Terraform利用費まとめて請求させていただくこともできて非常に便利です。ぜひ弊社経由のご契約もご検討ください。

そのほか同社では、Terraform Cloud(現:HCP Terraform)をクラスメソッドのCPPO経由で利用しています。以前からTerraformでAWSのインフラを構成・管理していましたが、「エンジニア間の作業のバッティングがあった」といいます。

「サービス開発のなかで、あるエンジニアが書いたコードを、他のメンバーが気がつかずに上書きしてしまったり、あとから振り返ってメンバーの作業内容が分からなかったりするという課題がありました。チーム開発の統制が取れない状況を是正するため、Terraform Cloudを導入しました。クラスメソッド経由にしたのは、AWSの費用と合算請求になるので、事務処理が楽だからです。ドルではなく円払いできるのもうれしいですね」

まとめ

matome.png

冒頭で「Terraform」の正しいアクセントの話をしてしまったせいで、登壇中「今言った「Terraform」のアクセント合ってたっけ?」「あ、またアクセント間違えたわ」と気になって勝手に一人で混乱していました笑 正しく発音できるように精進して参ります。

この記事をシェアする

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.