Terraformで始めるInfrastructure as Code

記事タイトルとURLをコピーする

みなさんこんにちは。マネージドサービス部MSS課の塩野(正)です。

買い物に行くと色んなお店でハロウィンのデコレーションをしているのを見かけますが、ハロウィンの飾りの中にクリスマスツリーが飾られているのを見かけると、頭の中がどっちなんだっけ?となってしまい、今だに慣れません(汗

Terraformで始めるInfrastructure as Code

さてさて、ここから本題に入っていきたいと思います。業務上IaCツールを使用することはありますが、今回はInfrastructure as Code(IaC)ツールの代表格、Terraformについて取り上げてみました。クラウドインフラの管理や自動化を行う上でとても便利なツールですので、効率的なインフラ構築を目指しているのにTerraformは使ったことないという方はぜひ取り入れてみてください!

Terraformとは

Terraformは、HashiCorp社が開発したオープンソースのInfrastructure as Code(IaC)ツールです。2014年に登場して以来、多くのエンジニアに支持され、現在では最も人気のあるIaCツールの一つとなっています。

Terraformの基本概念

Terraformの核心は、インフラストラクチャをコードとして扱うという考え方です。従来、サーバーやネットワークの設定は手作業で行われることが多く、時間がかかり、ミスも発生しやすいものでした。Terraformを使用することで、これらの作業をコード化し、自動化することができます。もちろんAWSではCloudformationやCDKなどもTerraformと同様にコードでインフラを管理するツールではありますが、Terraformの魅力はAWSだけに限らず様々なクラウド環境のインフラをコードで管理できる点です。

そんなTerraformですが、コードはHashiCorp Configuration Language(HCL)という独自の言語を使用してインフラの構成を記述します。

Terraformの主な特徴

  1. マルチクラウド対応: AWS、Azure、Google Cloud Platformだけでなく、New RelicやDatadogを含む多くのクラウドプロバイダーに対応しています。

  2. 宣言的な構文: 望ましいインフラの状態を記述するだけで、Terraformが必要な操作を判断して実行します。

  3. 状態管理: Terraformは、現在のインフラの状態を追跡し、変更が必要な箇所のみを更新します。

  4. モジュール化: コードの再利用性を高め、大規模なインフラ管理を効率化します。

  5. プラン機能: 変更を適用する前に、どのような変更が行われるかを事前に確認できます。

Terraformの動作原理

Terraformの基本的な動作フローは以下の通り。

  1. 構成ファイルの作成: HCLを使用してインフラの構成をコードで記述します。

  2. 初期化: terraform initコマンドで必要なプロバイダーをダウンロードします。

  3. プラン: terraform planコマンドで変更内容を確認します。

  4. 適用: terraform applyコマンドで実際にインフラを構築または変更します。

  5. 破棄: 不要になったリソースはterraform destroyコマンドで削除できます。

Terraformは、これらの操作を通じて、コードで定義されたインフラの状態と実際のインフラの状態を一致させます。

Terraformを使うことによるメリットとデメリット

Terraformの導入を検討する際は、そのメリットとデメリットを十分に理解することが大事なため、Terraformを使用することで得られる主なメリットと、考慮すべきデメリットについて見ていきましょう。

メリット

  1. インフラの一貫性確保 Terraformを使用することで異なる環境(開発、テスト、本番など)間でインフラの一貫性を保つことが容易になります。同じコードを使用して各環境を構築できるため、環境間の差異を最小限に抑えることができます。これにより、「開発環境では動作するが本番環境では動作しない」といった問題を大幅に減らすことができるでしょう。

  2. バージョン管理とコラボレーションの改善 インフラの構成をコードとして管理することで、Gitなどのバージョン管理システムを使用できるようになります。これによりインフラの変更履歴を追跡し、必要に応じて以前の状態に戻すことが可能になります。またチーム内でのコードレビューを通じてインフラ構築の品質向上が期待できます。

  3. 自動化による効率化 Terraformを使用することで、インフラの構築や変更を自動化できます。これにより手動での作業時間を大幅に削減し、人為的ミスのリスクも低減できるでしょう。特に大規模なインフラや複雑な環境では、この自動化による効率化の効果が大きく期待できます。

  4. マルチクラウド環境の統一管理 Terraformは多くのクラウドプロバイダーに対応しているため、異なるクラウド環境を単一のツールで管理できます。これは、ハイブリッドクラウドやマルチクラウド戦略を採用している組織にとって特に有益です。各クラウドプロバイダーの固有のツールを学ぶ必要がなく、Terraformの知識だけで複数のクラウド環境を操作できます。

  5. コスト最適化 Terraformを使用することで、不要なリソースの特定と削除が容易になります。またインフラがコード化されているため、必要に応じてリソースをスケールアップ/ダウンすることを容易におこなうことが可能です。これによりクラウドリソースの無駄を減らし、コストを最適化することができるようになります。

  6. ドキュメンテーションの改善 Terraformのコードは、それ自体がインフラの構成を示すドキュメントとしての役割を果たします。これにより別途詳細なドキュメントを作成・維持する必要性が減少し、常に最新の状態を反映したインフラの「設計図」を持つことができます。

  7. モジュール化による再利用性の向上 Terraformではコードをモジュール化することができ、これにより共通のインフラコンポーネントを再利用可能な形で管理できます。これは大規模な組織や複数のプロジェクトを抱える環境で特に有用です。ベストプラクティスをモジュールとして共有することで、組織全体のインフラ品質を向上させることができます。

  8. プロビジョニングの高速化 手動でのインフラ構築と比較して、Terraformを使用したプロビジョニングは非常に高速です。特に同じ構成を複数回デプロイする必要がある場合(例:テスト環境の複製)にその効果はとても大きいため、開発やテストのサイクルを短縮することができ、全体的な生産性を向上させることができるでしょう。

デメリット

  1. 学習曲線の存在 Terraformを効果的に使用するためには、HCLの文法やTerraformの概念を学ぶ必要があります。既存のインフラ管理方法に慣れているチームにとっては、この新しいアプローチへの移行が初期段階では負担になる可能性があります。特にプログラミングの経験が少ないインフラエンジニアにとっては、コードベースのアプローチに慣れるまでに時間がかかる場合があります。

  2. 状態管理の複雑さ Terraformは状態ファイル(terraform.tfstate)を使用してインフラの現在の状態を追跡します。この状態ファイルの管理は特にチーム環境では複雑になる可能性があります。状態ファイルの不適切な管理は、競合や不整合を引き起こす可能性があり、慎重な取り扱いが必要です。

  3. バージョン互換性の問題 Terraformは活発に開発が進められているツールであり、頻繁にアップデートがリリースされます。新しいバージョンがリリースされると、既存のコードとの互換性の問題が発生する可能性があります。これは長期的なプロジェクトや大規模な環境で特に問題になる可能性があります。

  4. プロバイダーの制限 Terraformは多くのクラウドプロバイダーをサポートしていますが、各プロバイダーの最新機能に対応するまでにはタイムラグが生じることがあります。これによりクラウドプロバイダーの新機能を即座に利用できない場合があります。

  5. デバッグの難しさ Terraformのエラーメッセージは時として不明確で、問題の根本原因を特定するのが難しい場合があります。特に複雑な依存関係を持つインフラでは、デバッグに時間がかかることがあります。

  6. 大規模環境での性能問題 非常に大規模なインフラ環境では、Terraformの実行に時間がかかる場合があります。特に多数のリソースを管理する場合や、複雑な依存関係がある場合はこの影響を受けます。

  7. 既存インフラの統合の難しさ 既存のインフラをTerraformの管理下に置く(インポートする)プロセスは、時として複雑で時間がかかる場合があります。特に長年運用されてきた大規模なレガシー環境では、この移行プロセスが大きな課題となる可能性があります。

  8. セキュリティリスク Terraformの構成ファイルでも、センシティブな情報(APIキーやパスワードなど)を扱うものがあります。これらの情報を安全に管理し、不適切な露出を防ぐための追加的な措置が必要となります。

これらのメリットとデメリットを慎重に検討し、自組織の状況や目標に照らし合わせて、Terraformの導入が適切かどうかを判断することが重要です。多くの場合はデメリットは適切な計画と管理によって軽減できるものであり、長期的にはメリットがデメリットを上回ることが多いと考えています。

Terraformの使い方

Terraformの基本的な使い方を理解することは、効果的なインフラ管理の第一歩。WindowsとMacでのTerraformのセットアップ方法、主要なファイルの種類と用途、コードの書き方、そして実行方法について見ていきましょう。

Windowsでの設定方法

Windowsでのterraformのセットアップは比較的簡単です。以下の手順に従ってインストールを行います。

  1. Terraformのダウンロード:

  2. ファイルの解凍:

    • ダウンロードしたzipファイルを解凍します。
    • 解凍するとterraform.exeというファイルが出てきます。
  3. 環境変数の設定:

    • terraform.exeを配置したフォルダのパスを環境変数PATHに追加します。
    • 例えば、C:\terraformにファイルを配置した場合、このパスを環境変数に追加します。
  4. インストールの確認:

    • コマンドプロンプトを開きます。
    • terraform --versionと入力し、Terraformのバージョン情報が表示されることを確認します。

これでWindowsでのTerraformのセットアップは完了です。

Macでの設定方法

Macでは、主にHomebrewを使用してTerraformをインストールします。以下の手順に従ってください。

  1. Homebrewのインストール:

    • まだHomebrewをインストールしていない場合は、ターミナルで以下のコマンドを実行します: /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
  2. Terraformのインストール:

    • ターミナルで以下のコマンドを実行します: brew tap hashicorp/tap brew install hashicorp/tap/terraform
  3. インストールの確認:

    • ターミナルでterraform --versionと入力し、Terraformのバージョン情報が表示されることを確認します。

これでMacでのTerraformのセットアップは完了です。

ファイルの種類と用途

Terraformプロジェクトでは、主に以下の種類のファイルを使用します。各ファイルには特定の役割があり、プロジェクトの構造化と管理に重要です。

  1. メインの構成ファイル (.tf)

    • 拡張子: .tf
    • 用途: インフラストラクチャのリソースを定義する主要なファイルです。
    • 例: main.tf, network.tf, compute.tf
    • 内容: リソース定義、データソース、プロバイダー設定などが含まれます。 hcl resource "aws_instance" "example" { ami = "ami-0123456789abcdef" instance_type = "t2.micro" }
  2. 変数定義ファイル (variables.tf)

    • 拡張子: .tf
    • 用途: プロジェクトで使用する変数を定義します。
    • 例: variables.tf
    • 内容: 変数の型、デフォルト値、説明などを指定します。 hcl variable "instance_type" { type = string default = "t2.micro" description = "EC2 instance type" }
  3. 出力定義ファイル (outputs.tf)

    • 拡張子: .tf
    • 用途: Terraform実行後に表示または他のモジュールで使用する値を定義します。
    • 例: outputs.tf
    • 内容: リソースの属性や計算された値を出力として定義します。 hcl output "instance_ip_addr" { value = aws_instance.example.public_ip description = "The public IP address of the main server instance." }
  4. ローカル値定義ファイル (locals.tf)

    • 拡張子: .tf
    • 用途: プロジェクト内で再利用する値や式を定義します。
    • 例: locals.tf
    • 内容: 複雑な式や頻繁に使用する値をローカル値として定義します。 hcl locals { common_tags = { Project = "MyProject" Owner = "DevOps Team" } }
  5. 変数値設定ファイル (.tfvars)

    • 拡張子: .tfvars または .auto.tfvars
    • 用途: 変数に具体的な値を割り当てます。環境ごとに異なる設定を管理するのに便利です。
    • 例: production.tfvars, development.auto.tfvars
    • 内容: 変数名と値のペアを記述します。 hcl instance_type = "t2.large" region = "us-west-2"
  6. バックエンド設定ファイル (backend.tf)

    • 拡張子: .tf
    • 用途: Terraformの状態ファイルの保存場所と方法を指定します。
    • 例: backend.tf
    • 内容: リモートバックエンド(S3、Terraform Cloudなど)の設定を記述します。 hcl terraform { backend "s3" { bucket = "my-terraform-state" key = "prod/terraform.tfstate" region = "us-east-1" } }
  7. プロバイダー設定ファイル (providers.tf)

    • 拡張子: .tf
    • 用途: 使用するプロバイダーとその設定を定義します。
    • 例: providers.tf
    • 内容: プロバイダーの指定、バージョン制約、認証情報などを記述します。 hcl provider "aws" { region = "us-west-2" version = "~> 3.0" }
  8. モジュール定義ファイル

    • 拡張子: .tf
    • 用途: 再利用可能なインフラストラクチャコンポーネントを定義します。
    • 例: モジュールディレクトリ内のmain.tf, variables.tf, outputs.tf
    • 内容: モジュール固有のリソース、変数、出力を定義します。
  9. 状態ファイル (terraform.tfstate)

    • 拡張子: .tfstate
    • 用途: Terraformが管理するインフラストラクチャの現在の状態を保存します。
    • 注意: このファイルは自動生成されるため、直接編集しないでください。
  10. ロックファイル (.terraform.lock.hcl)

    • 拡張子: .hcl
    • 用途: プロバイダーのバージョンをロックし、一貫性を保ちます。
    • 注意: このファイルはバージョン管理システムにコミットすべきです。

これらのファイルを適切に使用することでTerraformプロジェクトを構造化し、管理しやすくすることができるようになります。プロジェクトの規模や複雑さに応じて必要なファイルを選択し、効果的に組み合わせましょう。

コードの書き方

Terraformのコードは主にHCL (HashiCorp Configuration Language) で記述します。HCLは読みやすく書きやすい設計になっています。

リソースの定義

resource "aws_instance" "example" {
  ami           = "ami-0123456789abcdef"
  instance_type = "t2.micro"

  tags = {
    Name = "HelloWorld"
  }
}

この例ではAWS EC2インスタンスを定義しています。resourceブロックの後にリソースタイプ(aws_instance)とリソース名(example)を指定しています。

変数の使用

variable "instance_type" {
  default = "t2.micro"
}

resource "aws_instance" "example" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = var.instance_type
}

変数を使用することで、コードの再利用性と柔軟性が向上します。

データソースの利用

data "aws_ami" "ubuntu" {
  most_recent = true
  owners      = ["099720109477"] # Canonical

  filter {
    name   = "name"
    values = ["ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*"]
  }
}

resource "aws_instance" "example" {
  ami           = data.aws_ami.ubuntu.id
  instance_type = "t2.micro"
}

データソースを使用することで、既存のリソースの情報を取得し、新しいリソースの作成に利用できます。

実行の仕方

Terraformの実行は以下の手順で実施します。

  1. 初期化: プロジェクトディレクトリでterraform initを実行し、必要なプロバイダーをダウンロードします。

  2. プラン: terraform planを実行して、変更内容を確認します。

  3. 適用: terraform applyを実行して、実際に変更を適用します。

  4. 破棄: 不要になったリソースはterraform destroyで削除できます。

ベストプラクティス

  1. バージョン管理: Terraformのコードはバージョン管理システム(GitなどのVCS)で管理しましょう。

  2. モジュール化: 再利用可能なコンポーネントはモジュールとして切り出し、コードの重複を避けましょう。

  3. 状態管理: tfstateファイルはS3やTerraform Cloudなどのリモートバックエンドで管理し、チーム間で共有しましょう。

  4. 変数の活用: 環境ごとに異なる値は変数として定義し、柔軟性を持たせます。

  5. コードフォーマット: terraform fmtコマンドを使用して、コードを一貫したスタイルに保ちます。

  6. ワークスペースの利用: 複数の環境(開発、ステージング、本番など)を管理する場合は、ワークスペース機能を活用します。

Terraformを効果的に使用するには、これらの基本的な概念と実践を理解し、適切に適用することが重要です。また、常に公式ドキュメントを参照し、最新のベストプラクティスや機能を把握するよう心がけましょう。

まとめ

Terraformの基本的な部分についてまとめてみました。複雑なことをしない限りはコードの記載の難易度は低いため、とりあえずIaCを初めて見たい方には割とオススメかと思っています。インフラ基盤に特化したIaCツールとこういったマルチベンダーのツールでのメリット、デメリットはもちろんありますが、Terraformを覚えておけば他のインフラ基盤への流用ができますので、まだ触ったことはないけど・・という方は、お時間があればぜひチャレンジしてみてください。

この記事がどなたかのお役に立てれば幸いです。

関連記事

blog.serverworks.co.jp

blog.serverworks.co.jp

◆ 塩野 正人
◆ マネージドサービス部 所属
◆ X(Twitter):@shioccii
◆ 過去記事はこちら

前職ではオンプレミスで仮想化基盤の構築や運用に従事。現在は運用部隊でNew Relicを使ってサービス改善に奮闘中。