Terraformの面接ではstate(状態)が中心になります。現実のトラブルの多くはstateに起因するからです。誰がstateを保持するのか、誰が同時に変更できるのか、そして実際のインフラがstateから乖離したときに何が起きるのか。その次に、モジュール、環境、安全な変更、そしてチームでTerraformをどう運用するかが問われます。
以下は回答付きの25問です。HashiCorpは2023年にTerraformのライセンスを変更し、コミュニティフォークのOpenTofuも存在するので、話の流れで出てきたらチームがどちらを使っているかに触れておきましょう。基本的な考え方とコマンドはどちらも同じです。
基礎
1. Terraformとは何か、またInfrastructure as Codeとは何か?
Terraformは、インフラを設定ファイルで定義し、プロバイダーのAPIを通じて適用するためのツールです。Infrastructure as Codeとは、コンソールでクリックして組み立てるのではなく、構成を書き留めて、バージョン管理し、レビューし、再現可能にすることを意味します。
2. 宣言型と命令型の違いは何か?
Terraformは宣言型です。望む最終状態を記述すれば、Terraformが手順を導き出します。命令型のスクリプトでは手順を自分で書き、2回実行すると壊れてしまうことがあります。
3. Terraformの主なコマンドは何か?
| コマンド | 内容 |
|---|---|
| terraform init | プロバイダーとモジュールをダウンロードし、バックエンドを設定する |
| terraform validate | 設定が有効かどうかを検証する |
| terraform fmt | ファイルをフォーマットする |
| terraform plan | 何が変更されるかを表示する |
| terraform apply | 変更を適用する |
| terraform destroy | 管理対象のリソースを削除する |
| terraform import | 既存のリソースを管理下に取り込む |
| terraform state | stateを検査・編集する |
4. プロバイダー、リソース、データソースとは何か?
プロバイダーは、AWS、Azure、KubernetesなどのAPIとやり取りするプラグインです。リソースは、Terraformが作成・管理するものです。データソースは、既存のVPCや最新のAMIなど、すでに存在するものの情報を読み取ります。
5. 変数、出力、ローカルとは何か?
入力変数は設定をパラメーター化します。出力は値を公開し、コマンドラインや他のモジュールから利用できるようにします。ローカルはモジュール内の名前付き式で、繰り返しを避けるために使います。
State
6. Terraformのstateファイルとは何か、なぜ重要なのか?
stateは設定と実際のリソースを対応付け、その属性を保存します。Terraformは設定、state、実際の環境を比較して変更を計画します。stateを失うと、Terraformは存在するものを再作成しようとするかもしれません。またシークレットを含む可能性があるため、機密情報として扱いましょう。
7. stateはどこに保存すべきか?
個人のノートPCではなく、リモートバックエンドに保存します。例えば、S3とDynamoDBテーブル(または新しいネイティブS3ロック)、Azure Storage、Google Cloud Storage、Terraform Cloudなどです。バケットのバージョニング、暗号化、アクセス制限を有効にしましょう。
8. stateロックとは何か?
2人または複数のパイプラインが同時にapplyしてstateを破損させるのを防ぎます。ほとんどのリモートバックエンドが対応しています。実行がクラッシュした場合は、誰もまだapplyしていないことを確認したうえで、terraform force-unlockで古いロックを解除する必要があるかもしれません。
9. ドリフトとは何か、どう対処するか?
ドリフトとは、実際のインフラがstateと異なる状態のことです。通常は誰かが手動で変更したことが原因です。terraform plan(またはplan -refresh-only)で確認できます。applyして変更を元に戻すか、コードを実際の状態に合わせて更新するかを判断します。
10. 既存のリソースをTerraformの管理下に取り込むには?
リソースブロックを書き、terraform import <address> <id>を実行します。新しいバージョンではimportブロックを使うこともできます。その後planを実行し、変更が表示されなくなるまでコードを調整します。
11. 環境やチームごとにstateを分割するには?
環境とコンポーネントごとに別々のstateを使います。例えば、ネットワーク用に1つ、アプリごとに1つ、環境ごとに1つといった具合です。これにより影響範囲を限定し、planを高速化できます。値の共有には出力とデータソース、またはリモートstateを使います。
モジュールと構造
12. モジュールとは何か、どのようなときに書くべきですか?
モジュールとは、入力と出力を持つ再利用可能なリソースのまとまりです。VPCやサービスなど、同じパターンを繰り返しているときに、レビュー済みの単一バージョンとして使いたい場合に書きます。モジュールは小さく焦点を絞り、適切なデフォルト値を設定し、バージョン管理しましょう。
13. dev、staging、productionをどのように管理しますか?
一般的な選択肢は、それぞれ独自のstateと変数ファイルを持つ別々のディレクトリやリポジトリ、またはworkspacesです。多くのチームは環境ごとに別々のstateを好みます。workspacesは同じコードを共有するため、誤った環境にapplyしやすくなるからです。同じモジュールを異なる変数値で使いましょう。
14. workspacesとは何ですか?
1つのバックエンドと構成内における、名前付きのstateです。ブランチごとのテスト環境など、同じセットアップの一時的なコピーには便利ですが、本番環境を強固に分離するものではありません。
15. countとfor_eachの違いは何ですか?
countは位置でインデックスされた複数のコピーを作成します。for_eachはmapまたはsetの各項目ごとに、名前をキーとして1つずつ作成します。for_eachを優先しましょう。countのリストの途中から項目を削除するとインデックスがずれ、リソースが破棄・再作成される可能性があるからです。
16. depends_onは何をしますか?
Terraformが参照から依存関係を検出できない場合に、明示的な依存関係を追加します。ほとんどの依存関係は別のリソースの属性を参照することで生まれるため、使用は控えめにしましょう。
安全な変更と操作
17. lifecycleルールとは何ですか?
create_before_destroyは先に代替を作成し、prevent_destroyは削除をブロックし、ignore_changesはTerraform外部で変更された属性をスキップし、replace_triggered_byは別のリソースが変更されたときに強制的に置き換えます。
18. Terraformでシークレットをどのように扱いますか?
ハードコードしてはいけません。シークレットマネージャーや環境変数を使い、変数と出力をsensitiveとしてマークし、値がstateに残る可能性があることを忘れずにstateを保護しましょう。バージョン管理された平文の変数ファイルを通じてシークレットを渡すのは避けましょう。
19. 変更を安全にレビューしてapplyするにはどうしますか?
プルリクエストでplanを実行し、planの出力をレビューし、承認を必須にし、保存されたplanを使ってパイプラインからapplyすることで、レビューされた内容がそのまま実行されるようにします。plan内のdestroyやreplaceの行に注意しましょう。
20. planがデータベースを破棄して再作成すると表示しました。どうしますか?
一旦止めて、原因を調べます。よくある原因は、不変属性の変更、リソースの名前変更、モジュールの移動です。アドレスの変更を修正するにはmovedブロックやterraform state mvを使い、必要に応じてignore_changesやprevent_destroyを使い、リスクのあるapplyの前にはバックアップを取得しましょう。
21. リソースを破棄せずに名前変更や移動をするにはどうしますか?
コード内でmovedブロックを使うか、terraform state mvでstate内のアドレスを変更します。その後planを実行し、destroyがないことを確認しましょう。
22. バージョンをどのように固定しますか?
Terraformにはrequired_versionを、プロバイダにはバージョン制約付きのrequired_providersを使い、.terraform.lock.hclファイルをコミットして全員が同じプロバイダビルドを使うようにします。意図的にアップグレードし、changelogを読みましょう。
実践的・シナリオ問題
23. provisionersとは何で、使うべきですか?
provisionersは作成後にリソース上でスクリプトを実行します。stateで追跡されず、失敗の処理が難しいため、最後の手段です。cloud-init、Packerなどのツールでビルドしたイメージ、または構成管理を優先しましょう。
24. 複数の環境を持つチーム向けにTerraformをどのように構成しますか?
「バージョン付きリリースの共有モジュール用リポジトリと、環境ごと・コンポーネントごとにディレクトリを持つliveリポジトリを用意します。それぞれがロック付きの独自のリモートstateを持ちます。パイプラインはプルリクエストでfmt、validate、planを実行し、承認を必須とし、マージ時にapplyします。アクセスは短命な認証情報を通じ、ポリシーチェックでリスクのある変更を検出します。」
25. 誰かがコンソールでリソースを変更し、Terraformがそれを元に戻そうとしています。どうしますか?
なぜ変更したのかを確認します。緊急の修正であれば、コードを一致するように更新してapplyし、変更を保持します。誤りであれば、applyして元に戻します。その後、コンソールの書き込みアクセスを制限するなどの統制を追加し、再発を防ぎます。
準備の方法
リモートバックエンド、モジュール、2つの環境を持つ小さなプロジェクトを作りましょう。movedブロックでの名前変更、import、driftの修正を練習しましょう。planが予想外だった経験と、そのときどうしたかを説明できるようにしておきましょう。関連するクラウドのトピックについては、AWS面接ガイドとKubernetesガイドをご覧ください。
答えは声に出して言いましょう。特にstateに関する質問は説明が混乱しがちです。模擬面接の記録を見れば、どこで詰まったかがわかります。ライブ面接では、AIツールに関する雇用主のルールに従いましょう。
YesToTheOfferでTerraform面接の回答を練習しましょう
模擬技術面接を実行し、Stateとモジュールについて声に出して説明し、後で文字起こしを確認します。30分無料、サブスクリプションなし。



