はじめに
現代のインフラ管理では、コードを使って環境を構築・管理する「Infrastructure as Code (IaC)」が重要視されています。その中でも、Terraformは最も人気のあるIaCツールの1つです。本記事では、Terraformの基本からAWS S3バケットを構築する実践例まで、初心者にも分かりやすく解説します。
Terraformとは?IaCの概要とメリット
IaCとは?
IaCは「インフラ構成をコードとして定義し、自動化する」概念です。従来の手作業によるインフラ構築では、設定のばらつきやヒューマンエラーが起きやすく、再現性や効率性に課題がありました。IaCを導入することで、これらの問題を解決し、次のようなメリットを得ることができます。
- 再現性
コードで定義されたインフラ構成を元に、何度でも正確に同じ環境を再構築可能です。これにより、開発環境や本番環境を統一することが容易になります。 - 可視化
インフラ構成がコードとして明確に記録されるため、ドキュメント代わりにもなります。誰が見てもインフラの全体像が把握できる点は、チーム開発において特に有用です。 - 自動化
手動で行っていた作業をコードで自動化することで、時間を節約し、ヒューマンエラーを削減します。また、変更や削除も簡単に管理できるため、運用負荷を軽減します。 - バージョン管理
コードはGitなどのバージョン管理システムで管理できるため、誰がどのような変更を行ったかを追跡できます。変更前の状態に簡単に戻すことも可能です。
Terraformの特徴
Terraformは、IaCを実現するツールの中でも特に人気が高いオープンソースソフトウェアです。その理由は、以下の特徴にあります。
- 宣言的な構文
Terraformでは、「現在の状態から理想の状態へ変化させる」手順を明示的に記述する必要はありません。理想の構成をコードで宣言するだけで、Terraformが最適な方法で変更を実行します。これにより、ユーザーは複雑な手順に悩まされることなく、必要な構成を簡単に実現できます。
この例では、AWS上で特定のAMIを使ったインスタンスが作成されるよう、構成を簡潔に宣言しています。
resource "aws_instance" "example" {
ami = "ami-12345678"
instance_type = "t2.micro"
}
- 複数クラウド対応
TerraformはAWS、Azure、Google Cloudなどの主要クラウドプロバイダーに加え、Kubernetes、VMware、オンプレミス環境にも対応しています。一つのツールで複数の環境を管理できるため、クラウド間の移行やハイブリッド構成にも柔軟に対応可能です。 - 管理の簡略化(Stateファイルの活用)
Terraformはインフラの現在の状態を「Stateファイル」として管理します。このファイルは、リソースの作成・変更・削除の際に重要な役割を果たします。Stateファイルを利用することで、Terraformは既存のリソースを把握し、必要な変更のみを適用する賢い管理が可能になります。 - 拡張性とモジュール化
Terraformには「モジュール」という仕組みがあり、リソース定義を再利用可能な単位にまとめることができます。これにより、大規模なインフラでも効率的に管理ができ、チームでの作業もスムーズに進められます。 - プラン機能による安全性
実際にインフラを変更する前に、terraform plan
コマンドを使って変更内容を確認できます。これにより、誤操作を未然に防ぐことが可能です。
Terraform環境構築
MacOSのHomebrewを使ったTerraformのインストール方法になります。
他OSの場合は下記サイトを参考にしてください。

下記コマンドを叩きます。
brew tap hashicorp/tap
brew install hashicorp/tap/terraform
terraform --version
コマンドを実行し、versionが表示されたら完了です。
Terraformの基本コマンドと構文
Terraformの操作は主に以下のコマンドを使用します。
terraform init
: 初期化terraform plan
: 実行計画の確認terraform apply
: 実行terraform destroy
: 削除
HCLの基本構文
Terraformでは、インフラ構成を定義するために、HCL (HashiCorp Configuration Language) を使用します。この言語は、宣言的かつ人間が読みやすいように設計されています。ここでは、HCLの基本的な構文を詳しく解説し、初心者が理解しやすいようにポイントを整理します。
基本構成要素
Provider(プロバイダー)
プロバイダーは、Terraformが操作するクラウドサービスやインフラ環境(例:AWS、Azure、Google Cloud)を指定します。プロバイダーの設定は必須で、どのプロバイダーを使うのか、必要な認証情報や設定を記述します。
// 構文
provider "<provider_name>" {
<key> = "<value>"
<key> = "<value>"
...
}
// 例
provider "aws" {
region = "us-east-1"
access_key = "your-access-key"
secret_key = "your-secret-key"
}
provider "google" {
project = "my-google-cloud-project"
region = "asia-northeast1"
}
provider "azurerm" {
features = {}
subscription_id = "your-subscription-id"
client_id = "your-client-id"
client_secret = "your-client-secret"
tenant_id = "your-tenant-id"
}
provider "kubernetes" {
config_path = "~/.kube/config"
cluster = "my-kubernetes-cluster"
}
provider "providerName"
terraformが操作するプロバイダーを指定します。プロバイダーとは、Terraformがリソースを作成・管理するために利用するクラウドやサービスです。
- 例
"aws"
: AWSプロバイダーを使用。"google"
: Google Cloudプロバイダーを使用。"azure"
: Microsoft Azureプロバイダーを使用。"kubernetes"
: Kubernetesクラスターを管理するプロバイダー。"helm"
: Helmチャートをデプロイするプロバイダー。
key
プロバイダー固有の設定項目を指定します。プロバイダーが要求する情報や、接続設定、認証情報、動作環境などを指定するキーです。
- 一般的なキー:
region
: クラウドプロバイダーの対象リージョンを指定。- 例:
"us-east-1"
(AWSの場合)、"asia-northeast1"
(Google Cloudの場合)。
- 例:
access_key
/secret_key
: クラウドへのアクセスに必要な認証情報。project
: Google Cloudでプロジェクトを指定。subscription_id
: AzureのサブスクリプションID。cluster
: Kubernetesプロバイダーで対象のクラスター名を指定。config_path
: 設定ファイル(例: Kubernetesのkubeconfig)のパス。
value
各key
に対応する値を指定します。具体的な値は環境や設定によって異なります。
- 例:
region
の場合:"us-west-2"
(AWSの米国西部リージョン)"asia-east1"
(Google Cloudのアジア東部リージョン)
access_key
/secret_key
の場合:"your-access-key"
/"your-secret-key"
(AWSアクセスキーとシークレットキー)
project
の場合:"my-google-cloud-project"
(Google Cloudプロジェクト名)
cluster
の場合:"my-kubernetes-cluster"
(Kubernetesクラスター名)
Resource(リソース)
リソースは、Terraformが作成・管理する具体的なインフラ要素を表します。例えば、AWSのS3バケット、EC2インスタンス、またはAzureのリソースグループなどです。
resource "<resource_type>" "<resource_name(コード内で一意な好きな名前)>" {
<attribute_key> = "<attribute_value>"
<attribute_key> = "<attribute_value>"
...
}
// 例 s3
resource "aws_s3_bucket" "example" {
bucket = "my-example-bucket"
acl = "private"
tags = {
Name = "ExampleBucket"
Environment = "Development"
}
}
//
resource "google_compute_instance" "vm_instance" {
name = "example-instance"
machine_type = "n1-standard-1"
zone = "us-central1-a"
boot_disk {
initialize_params {
image = "debian-cloud/debian-10"
}
}
network_interface {
network = "default"
access_config {
}
}
}
resource "kubernetes_namespace" "example" {
metadata {
name = "example-namespace"
}
}
resource "azurerm_virtual_network" "example" {
name = "example-vnet"
address_space = ["10.0.0.0/16"]
location = "East US"
resource_group_name = "example-resources"
}
<resource_type>
作成・管理するリソースの種類。
プロバイダー固有のリソースタイプ名を指定します。
- 例:
"aws_s3_bucket"
(AWSのS3バケット)"google_compute_instance"
(Google Cloudの仮想マシン)"azurerm_virtual_network"
(Azureの仮想ネットワーク)
<resource_name>
リソースをTerraform内で識別するローカル名。
ローカルスコープ内で一意であれば任意の名前を付けられます。
- 例:
"example"
(AWSのS3バケット)"vm_instance"
(仮想マシン)
<attribute_key>
リソースの属性や設定項目。
リソースの種類によって定義される必須またはオプションのキー。
- 例:
bucket
(S3バケットの名前)acl
(アクセス制御リスト)machine_type
(仮想マシンのタイプ)
<attribute_value>
各属性に対応する値。
静的な値や、変数、関数を利用できます。
- 例:
"my-example-bucket"
(S3バケット名)"private"
(非公開設定)
変数(Variables)
再利用性を高めるために、変数を定義できます。変数を使うと、同じ設定ファイルを複数の環境で使い回すことが容易になります。
variable "<variable_name>" {
<attribute_key> = "<attribute_value>"
<attribute_key> = "<attribute_value>"
...
}
// 例
variable "region" {
default = "us-east-1"
}
// 使い方
provider "aws" {
region = var.region
}
// 型指定と説明を追加
variable "instance_type" {
type = string
default = "t2.micro"
description = "The instance type for the EC2 instance."
}
//リスト型変数
variable "allowed_ips" {
type = list(string)
default = ["192.168.1.1", "192.168.1.2"]
description = "A list of IP addresses allowed to access the application."
}
// マップ型変数
variable "tags" {
type = map(string)
default = {
Environment = "Development"
Owner = "Admin"
}
description = "Tags to apply to all resources."
}
//検証ルール付き変数
variable "bucket_name" {
type = string
description = "The name of the S3 bucket."
validation {
condition = length(var.bucket_name) <= 63
error_message = "The bucket name must not exceed 63 characters."
}
}
<variable_name>
変数の名前を指定します。
この名前を使って、Terraform構成内で変数を参照します。
<attribute_key>
変数の属性を指定します。代表的な属性は以下の通りです
default
: 変数のデフォルト値。type
: 変数の型(例:string
,list
,map
など)。description
: 変数の説明(オプション)。validation
: 入力値の検証ルール(Terraform 0.13以降で使用可能)。
<attribute_value>
各属性に対応する値を指定します。
出力(Outputs)
実行後にTerraformが管理しているリソースの値を出力するために使用します。これにより、リソースIDやURLなどの重要な情報を簡単に取得できます。
output "<output_name>" {
value = "<expression>" # 必須: 出力する値
description = "<description>" # 任意: 出力の説明
sensitive = <true|false> # 任意: 値を非表示にするかどうか
}
//例
output "bucket_name" {
value = aws_s3_bucket.example.bucket
}
output "instance_ip" {
value = aws_instance.web.public_ip
description = "The public IP address of the web server instance."
}
output "db_password" {
value = random_password.db.result
sensitive = true
}
<output_name>
出力の名前を定義します。
Terraform実行後に、この名前で出力を確認できます。
value
出力する値を指定します。リソースの属性や、変数、計算式などが使用できます。
オプションの属性
description
: 出力の用途を説明(任意)。sensitive
: センシティブな値を非表示にするかどうか(デフォルトはfalse
)。- 例: パスワードや秘密鍵を出力する際に利用。
Terraform CLIの基本ワークフロー
- 初期化: プロジェクトの初期化を行います。
terraform init
- 計画の作成: 変更内容を確認します。
terraform plan
- 適用: 計画通りにインフラを構築します。
terraform apply
- 削除: リソースを削除します。
terraform destroy
AWS S3バケットの作成例
AWS CLIのセットアップ
awsにてリソースを作成できるようにするためにaws cliをインストールします。
インストール
下記サイトに従い、CLIをインストールします。
セットアップ
下記内容に従いawsの認証情報を登録します。
事前にaws IAMにて登録用のユーザーを作成しておいてください。
下記コマンドで対話モードで設定を行うことができます。
aws configure
Terraformプロジェクトの作成
プロジェクト用のディレクトリを作成
mkdir terraform-s3-example
cd terraform-s3-example
Terraform設定ファイル (main.tf
) を作成
provider "aws" {
region = "us-east-1"
}
resource "aws_s3_bucket" "example" {
bucket = "my-unique-bucket-name"
acl = "private"
}
Terraform
初期化
プロバイダー(AWS)のプラグインをダウンロードします。
成功すると、「Terraform has been successfully initialized!」と表示されます。
terraform init
計画確認
実行前に変更内容を確認します。
terraform plan
# 問題なければこんな出力が出る
# Plan: 1 to add, 0 to change, 0 to destroy.
実行
計画通りにリソースを作成します。
プロンプトで「Do you want to perform these actions?」と聞かれるので、yes
と入力します。
terraform apply
結果の確認
エラーが特に発生しなかった場合、AWS Management Consoleにログインし、S3の画面でバケットが作成されていることを確認しましょう。
リソースの削除
下記コマンドを入力します。
プロンプトで「Do you really want to destroy?」と聞かれるので、yes
と入力します。
その後、AWS Management ConsoleでS3バケットが削除されていることを確認します。
terraform destroy
Stateファイル
TerraformのStateファイル(terraform.tfstate
)は、Terraformが管理しているインフラの現在の状態を記録する重要なファイルです。このファイルは、Terraformがインフラリソースの変更を正確に管理するための基盤として機能します。以下では、Stateファイルの役割、仕組み、管理方法、注意点について詳しく解説します。
Stateファイルの役割
- インフラの状態追跡
- TerraformはStateファイルにインフラリソースの最新状態を保存します。
- Stateファイルを元に、現状のインフラとTerraformコード(
*.tf
ファイル)で定義された理想状態の差分を計算します。
- 差分の検出
- Terraformが
plan
やapply
コマンドを実行する際、Stateファイルを参照して以下を判断します:- 追加(リソースがコードにあるがStateファイルにない場合)
- 変更(コードとStateファイルのリソース属性が異なる場合)
- 削除(Stateファイルにあるがコードにない場合)
- Terraformが
- パフォーマンスの向上
- クラウドAPIへの頻繁な問い合わせを減らし、パフォーマンスを最適化します。
Stateファイルの仕組み
ファイル構成
StateファイルはJSON形式で保存され、以下の情報を含みます:
- リソースタイプ:
- 例:
aws_s3_bucket
、google_compute_instance
。
- 例:
- リソース名:
- Terraform構成内でのローカル名(例:
example
)。
- Terraform構成内でのローカル名(例:
- 属性値:
- 実際に作成されたリソースの属性(例: バケット名、リージョン、ID)。
- メタデータ:
- Terraform固有の管理情報。
例(簡略化したStateファイルの一部)
{
"resources": [
{
"type": "aws_s3_bucket",
"name": "example",
"instances": [
{
"attributes": {
"bucket": "my-unique-bucket-name",
"acl": "private",
"region": "us-east-1"
}
}
]
}
]
}
Stateファイルの管理
ローカル管理
デフォルトでは、TerraformはStateファイルを作業ディレクトリ内にローカルファイル(terraform.tfstate
)として保存します。
- 利点:
- シンプルで設定が不要。
- 欠点:
- 複数人で作業する場合に競合が発生しやすい。
- ファイルの紛失や破損リスク。
リモート管理
チームでの作業や高可用性を確保するため、リモートバックエンドを使用します。
- 対応するバックエンド:
- AWS S3(+DynamoDBでロック管理)
- Azure Blob Storage
- Google Cloud Storage
- Terraform Cloud/Enterprise
- 設定例(AWS S3バックエンド)
bucket
: Stateファイルを保存するS3バケット。dynamodb_table
: ロック管理用のテーブル。
terraform {
backend "s3" {
bucket = "my-terraform-state-bucket"
key = "path/to/my/statefile.tfstate"
region = "us-east-1"
dynamodb_table = "terraform-lock-table"
}
}
Stateファイルの運用における注意点
- 直接編集の禁止
- StateファイルはTerraformが自動生成・管理します。
- 手動で編集すると、インフラの状態が不整合になり、意図しない変更や破壊を引き起こす可能性があります。
- バックアップの確保
- Stateファイルはインフラ管理の中核となるデータです。破損や紛失に備えて、定期的にバックアップを取得してください。
- センシティブな情報の取り扱い
- Stateファイルには、パスワードやキーなどのセンシティブな情報が含まれる場合があります。これを防ぐには、次の方法を検討してください:
- センシティブな情報は変数として扱い、環境変数やシークレット管理ツールで保護。
- Stateファイルを暗号化(リモートバックエンドの暗号化機能を利用)。
- Stateファイルには、パスワードやキーなどのセンシティブな情報が含まれる場合があります。これを防ぐには、次の方法を検討してください:
- ロック機能の活用
- 複数人が同時に
apply
操作を行うと競合が発生する可能性があります。リモートバックエンド(例: S3 + DynamoDB)を使用してロック機能を有効にしましょう。
- 複数人が同時に
Stateファイルの操作コマンド
TerraformはStateファイルを操作するためのいくつかのコマンドを提供します:
- Stateの確認
terraform show
- Stateファイルの内容一覧
terraform state list
- 管理しているリソースの一覧を表示。
- 特定リソースの情報表示:
terraform state show <resource_address>
- 例:
aws_s3_bucket.example
- 例:
- Stateファイルの移動
terraform state mv <source> <destination>
- リソースの名前変更やモジュール間の移動時に使用。
- Stateファイルからリソースを削除
terraform state rm <resource_address>
- Stateファイルからリソースを削除(実際のリソースは削除されない)。
初心者が注意すべきポイント
- Stateファイルのバックアップ
terraform.tfstate
は重要なファイルなので、適切に管理すること。
- クラウド料金
- リソースを作成後は削除を忘れないこと。
まとめ
Terraformは、IaCを通じて効率的なインフラ管理を可能にする強力なツールです。本記事で紹介した内容を参考に、実際に手を動かしながら理解を深めてみてください。次のステップでは、ネットワークや複雑なリソースの構成に挑戦してみるのも良いでしょう。
コメント