💡

Terraformハンズオン - できるだけ何も考えず、とりあえず使ってみよう

2024/07/28に公開

はじめに

「約5年開発してきた自社サービス(チケット販売、配信、EC、データ基盤など)にIaCを導入する」という自分のコンテキストがあり、実際にIaCとして、Terraformを本番運用しているサービスにゼロから導入するにあたって、なーんかしっくりくるまで大変だったなーという思いがあります。

その理由の一つに、IaCは「hello, world!」的なことを行うハードルが高いからだと思っています。記事を読んだり動画を見たりでなんとなく分かったつもりにはなるんだけど、実際に触ってみないことには真に理解できないということは不思議と多々あります。(hello, world一応あるけど実際にクラウドのインフラ作らないケースが多いのであんまおもしろくはないと思う)

これからIaCを導入する人、IaCが導入されているチームにいるけど一部開発者しか触れてなくて正直よく分かってない人向けに、まずはとりあえず何も考えずに、IaC(Terraform)を体験してみるのがいいかなと思い雑に書いています。なのでチームメンバー向けでもあり。

※できる限り環境構築が不要になるように、実際のクラウド(Google Cloud)のインフラリソースを構築します

とにかくハンズオンを始める

この記事を読むと嬉しいことがあるかもしれない人

  • IaCとしてTerraformを導入したいんだけど何から始めたらいいか分からない
  • なんかよくわからんけど、コード書いたらインフラできるんでしょ?くらいの理解で、実際に触ったことがないので正直ピンときてない
  • IaCがプロダクトに導入されてるけど、自分は触ったことないのでなんか触るの怖い
  • 触ってみたいけど、terraformインストールしたり、Google CloudやAWSなどどのプロバイダに対して実行したらいいんだか分からなくて結局手をつけられていない

Terraform導入前のコンテキスト

※参考までになので飛ばしていいです

  • 約5年開発してきた自社サービス(チケット販売、配信、EC、データ基盤など)に、IaCを導入する
    • IaCの存在は知ってるけど手をつけられずにいた
  • それまでのインフラ管理
    • アプリケーションコードは Buildpack を使用してデプロイ
      • → コードから勝手にビルドしてデプロイ。
    • それ以外のインフラはコンソールで手動設定
  • ざっくりサービス技術スタック
    • フロントエンド
      • React x Typescript
    • バックエンド
      • Node x Typescript
    • monorepo運用

Terraformにしっくりくるまでの個人的ロードマップ

※参考までになので飛ばしていいです

ここでは書かないこと(需要あれば別途書きたい)

※参考までになので飛ばしていいです
ハンズオン後に必要あれば読む

  • 本番運用するにあたって気になるだろうこと(自分が本番運用を始めるにあたっていろいろ気になってなかなか進まなかったやーつ。現状は一定の解を持ってプロダクト運用できています。キーワードだけ置いておく)
    • なぜIaCが必要なんだろう?
    • IaCってTerraform以外も選択肢としてあるけど、Terraformでいいんだろうか?
      • Terraformは宣言的である
    • インフラ構築となると、コードの構成によっては改修するの大変なんじゃないか?最適なフォルダ構成があるんだろうか?
    • もしリファクタリングしたいってなったらどうするんだろう?
      • movedブロック
    • セキュアな情報はどう管理すればいいんだろう?
    • インフラがすでに本番稼働してるんだけどどうしたらいいんだろう?
      • importブロック
    • 開発環境や本番環境はどのように管理したらいいんだろう?
      • 分けよう
    • チームで運用する上で気をつけるべきことはなんだろう?
      • 単一ブランチを正とする。同じリソースを同時に修正する時は要注意
    • インフラコードの適用はどうするんだろう?ローカルからやるの?
      • GitHub Actionなどの実行環境を作る
    • Terraformでインフラリソースの構築ができるのはわかった。じゃあアプリケーションコードの変更をサービスに反映するにはどうしたらいいんだろう?
    • コードレビューってどうしたらいいんだろう?
      • tfcmtが便利
    • Terraformはどういう仕組みでインフラに変更を加えているんだろう?
    • フォーマットや文法チェック、静的解析はどうしたらいいんだろう?
      • terraform fmtterraform validate 、tflint
    • テストとかどうするんだろう?
    • あるインフラをコードに落とし込む時に何からやればいいんだろう?コードはどこから探したらいいんだろう?
    • 緊急対応で、IaC管理されているインフラを手動で設定したい場合はどうしたらいいんだろう?

ハンズオン

  • ※30min~1hくらい
  • ※自分はMacOSでやっています
  • ※dockerはインストールされている前提で進めます
  • ※Dockerなど、用意されているコードを理解しようとしないでください。目的はあくまでTerraformというコードで、インフラが出来上がることを体験することだけです。分からない部分は分からないまま受け入れてください。

ゴール

  • TerraformでCloud Run Serviceを作成し、URLにアクセスできる(webで以下が表示される)
  • Terraformで、Cloud Run Serviceに変更を加える
  • Terraformで、Cloud Run Serviceを削除する

事前準備

リポジトリをクローンする

git clone git@github.com:sbleru/terraform-handson.git
cd terraform-handson

gcloudやterraformを実行するためのコンテナ環境を構築し、コンテナに入る

# イメージのビルド
docker-compose build
# コンテナの起動
docker-compose up -d
# コンテナに入る
docker-compose exec tf-sandbox /bin/bash

以降、コンテナ内での処理

gcloud cliの認証を行う

# Googleプロジェクトを作成したいアカウントでGoogleログインする
gcloud auth login

Googleプロジェクトを作成する

my-tf-handson の名前で作成するため、名前を変更する場合は以降の処理を適宜書き換えてください

# Googleプロジェクトを作成する
export GOOGLE_PROJECT_ID=my-tf-handson
gcloud projects list | grep $GOOGLE_PROJECT_ID || gcloud projects create $GOOGLE_PROJECT_ID --name="My Terraform Hands On"

アクセスしてプロジェクトを確認してみる

echo https://console.cloud.google.com/home/dashboard?project=$GOOGLE_PROJECT_ID
# https://console.cloud.google.com/home/dashboard?project=my-tf-handson

クレデンシャルを生成する

gcloud auth application-default login

支払いの紐付けを行う(インフラリソースを作成するため、プロジェクトに請求アカウントを紐づける必要があります)

billingアカウントの確認と設定

gcloud beta billing accounts list
# ACCOUNT_ID            NAME              OPEN   MASTER_ACCOUNT_ID
# hogehoge  sbleru            True

対象のACCOUNT_IDを指定

export BILLING_ACCOUNT_ID=hogehoge

紐付けの実行

gcloud beta billing projects link $GOOGLE_PROJECT_ID --billing-account=$BILLING_ACCOUNT_ID

紐付け状態の確認

gcloud beta billing projects describe $GOOGLE_PROJECT_ID
  • ※初回のみ必要です
  • ※課金されないように、このハンズオンが終わり次第、プロジェクトを削除すると安心です

対象のプロジェクトをセットする

gcloud config set project $GOOGLE_PROJECT_ID

Terraformでインフラリソースを作成してみよう

事前準備の続きで、引き続きコンテナ内で操作します

Terraformの初期化(基本初回のみ)

# terraformの実行フォルダへ移動する
cd terraform/cloud_run_service_example/
# 初期化
terraform init

Terraformコードからどんなインフラが構築されるかの差分を確認する

terraform plan
# GOOGLE_PROJECT_ID を変更している場合は外から変数を渡してください
# terraform plan -var="google_project_id=$GOOGLE_PROJECT_ID"
  • plan結果
    Plan: 3 to add, 0 to change, 0 to destroy.
    
    • addが作成、changeが変更、destroyが削除の意味。ここでは3つのインフラリソースが作成されることがわかる

Terraformコードからインフラを適用する

# インフラの適用(yesを入れると実際に適用が開始されます)
terraform apply
# GOOGLE_PROJECT_ID を変更している場合は外から変数を渡してください
# terraform apply -var="google_project_id=$GOOGLE_PROJECT_ID"
#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

Cloud Run Serviceが作成されているか確認する

# 出力変数から、cloud run serviceのuriを確認する
terraform output
# cloud_run_service_uri = "xxx"

cloud_run_service_uri をブラウザアクセスしてみる

コンソールからCloud Run Serviceへアクセスしてみる

echo https://console.cloud.google.com/run?project=$GOOGLE_PROJECT_ID
# https://console.cloud.google.com/run?project=my-tf-handsonf

Terraformでインフラができました!!

Terraformでインフラリソースを変更してみよう

Cloud Run Serviceには環境変数を設定できるため、設定してみる。

現状を確認してみる
https://console.cloud.google.com/run/deploy/us-central1/cloudrun-service?project=my-tf-handson
「Cloud Run Serviceを選択」→「Edit」→「CONTAINER(S)」→「VARIABLES & SECRETS」→「Environment variables」

envブロックのコメントアウトを外してみる

terraform-handson/terraform/cloud_run_service_example/main.tf

https://github.com/sbleru/terraform-handson/blob/0500c2150d4fac1eb2869d29c3064cc845ceeeb2/terraform/cloud_run_service_example/main.tf#L10-L17

terraform planを実行する

terraform plan
  • + env となっており、環境変数が追加されることがわかる。

terraform applyを実行する

# yesと答える
terraform apply

再度確認してみる

https://console.cloud.google.com/run/deploy/us-central1/cloudrun-service?project=my-tf-handson

「Cloud Run Serviceを選択」→「Edit」→「CONTAINER(S)」→「VARIABLES & SECRETS」→「Environment variables」

環境変数が増えていることが確認できる

Terraformでインフラリソースを削除してみよう

※削除は危険な行為なので、本番運用の際は最善の注意を払う必要がありますが、今回はハンズオンなので気軽に消し飛ばしましょう

削除planを実行する

terraform plan -destroy
  • Plan: 0 to add, 0 to change, 3 to destroy. のように、destroyされる数が表示される

削除applyを実行する

terraform apply -destroy
  • yesと答えると削除が開始される

クラウドコンソールで確認してみる

https://console.cloud.google.com/run?referrer=search&project=my-tf-handson

削除されていることが確認できる

ここで再び作成処理を行うこともできます Terraformでインフラリソースを作成してみよう

その際作成されたCloud Run ServiceのURLが前回とは異なることに注目してください。つまり、同じCloud Run Serviceでも全く異なる実体が生成されます。

他のインフラリソースの変更もやってみる

この記事では掘り下げませんが、クラウドプロバイダーごとにインフラリソースを表現するコードドキュメントが提供されています。

今回はこちらのコードを持ってきています。いろいろ設定値があるので遊んでみてください。

google_cloud_run_v2_service | Resources | hashicorp/google | Terraform | Terraform Registry

プロジェクトの削除

ひととおり遊んで満足したらプロジェクトを削除してしまいましょう

(Cloud Run Serviceに関してはアクセスがなければ課金されないと思いますが)

gcloud projects delete $GOOGLE_PROJECT_ID

ハンズオン終わり!

おわりに

実際に本番運用を意識するとなると、 ここでは書かないこと で記載したようなことがいろいろ気になると思います。
ただ、とにかくTerraformを触ってみることができたことで、理解は進みやすくなるんじゃないかな、そうなっていたらいいな、と思います。
記事書けたら書きますmm

また、Terraform外観掴んだし、触ってみれたしって人はこの本読んだら大抵の問題は解決すると思います。
O'Reilly Japan - 詳解 Terraform 第3版
※NotebookLMにPDFぶっ込んで質問するのもおすすめです。

参考

Discussion