Terraformは、HashiCorp社が開発したオープンソースのインフラストラクチャ as コード(IaC)ツールです。Terraformを使用すると、クラウドプロバイダー(AWS、Azure、GCPなど)やその他のサービスのインフラストラクチャをコードとして定義、プロビジョニング、管理することができます。Terraformは宣言的な構成ファイルを使用して、インフラストラクチャのあるべき状態を記述し、その状態に到達するために必要なアクションを自動的に計画して実行します。
Terraformの基本的な仕組みは以下の通りです:
terraform init
コマンドを実行して、必要なプロバイダープラグインをダウンロードし、バックエンドを設定します。terraform plan
コマンドを実行して、現在の状態と目標の状態の差分を確認します。terraform apply
コマンドを実行して、計画された変更を実際のインフラストラクチャに適用します。terraform.tfstate
)に記録します。terraform destroy
コマンドを実行して、作成したリソースを削除します。構成ファイル作成 → terraform init → terraform plan → terraform apply → インフラストラクチャ構築 ↓ terraform destroy → インフラストラクチャ削除
Terraformの構成ファイルは、通常.tf
拡張子を持つファイルで、HCL(HashiCorp Configuration Language)またはJSONで記述されます。基本的な構成要素は以下の通りです:
要素 | 説明 | 例 |
---|---|---|
プロバイダー | 使用するクラウドプロバイダーやサービスを定義 | provider "aws" { region = "us-west-2" } |
リソース | 作成または管理するインフラストラクチャリソース | resource "aws_instance" "web" { ami = "ami-123456" } |
データソース | 既存のリソースからデータを取得 | data "aws_ami" "ubuntu" { most_recent = true } |
変数 | 構成で使用する入力変数 | variable "instance_type" { default = "t2.micro" } |
ローカル値 | 構成内で再利用する式や値 | locals { common_tags = { Environment = "Dev" } } |
出力値 | 他のモジュールや実行後に参照できる値 | output "instance_ip" { value = aws_instance.web.public_ip } |
モジュール | 再利用可能なインフラストラクチャコンポーネント | module "vpc" { source = "./modules/vpc" } |
バックエンド | 状態ファイルの保存場所と方法 | terraform { backend "s3" { bucket = "mybucket" } } |
provider "aws" {
region = "us-west-2"
}
resource "aws_instance" "example" {
ami = "ami-0c55b159cbfafe1f0" # Amazon Linux 2 AMI
instance_type = "t2.micro"
tags = {
Name = "example-instance"
}
}
output "instance_id" {
value = aws_instance.example.id
}
output "public_ip" {
value = aws_instance.example.public_ip
}
# variables.tf
variable "region" {
description = "AWS region"
type = string
default = "us-west-2"
}
variable "instance_type" {
description = "EC2 instance type"
type = string
default = "t2.micro"
}
variable "environment" {
description = "Deployment environment"
type = string
default = "dev"
}
# main.tf
provider "aws" {
region = var.region
}
module "vpc" {
source = "./modules/vpc"
environment = var.environment
cidr_block = "10.0.0.0/16"
}
resource "aws_instance" "web" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = var.instance_type
subnet_id = module.vpc.public_subnet_id
tags = {
Name = "web-server"
Environment = var.environment
}
}
# outputs.tf
output "vpc_id" {
value = module.vpc.vpc_id
}
output "instance_id" {
value = aws_instance.web.id
}
output "public_ip" {
value = aws_instance.web.public_ip
}
AWSでTerraformを使用するための基本的な手順は以下の通りです:
brew install terraform
wget https://releases.hashicorp.com/terraform/1.5.7/terraform_1.5.7_linux_amd64.zip
unzip terraform_1.5.7_linux_amd64.zip
sudo mv terraform /usr/local/bin/
choco install terraform
aws configure
export AWS_ACCESS_KEY_ID="your_access_key"
export AWS_SECRET_ACCESS_KEY="your_secret_key"
export AWS_DEFAULT_REGION="us-west-2"
provider "aws" {
region = "us-west-2"
access_key = "your_access_key"
secret_key = "your_secret_key"
}
terraform init
terraform plan
terraform apply
terraform destroy
Terraformを使用して管理できる主なAWSリソースの例:
resource "aws_instance" "web" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
key_name = "my-key"
vpc_security_group_ids = [aws_security_group.web.id]
subnet_id = aws_subnet.public.id
tags = {
Name = "web-server"
}
}
resource "aws_launch_configuration" "web" {
name_prefix = "web-"
image_id = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
security_groups = [aws_security_group.web.id]
lifecycle {
create_before_destroy = true
}
}
resource "aws_autoscaling_group" "web" {
name = "web-asg"
launch_configuration = aws_launch_configuration.web.name
min_size = 2
max_size = 5
desired_capacity = 2
vpc_zone_identifier = [aws_subnet.public.id]
tag {
key = "Name"
value = "web-server"
propagate_at_launch = true
}
}
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
enable_dns_support = true
enable_dns_hostnames = true
tags = {
Name = "main-vpc"
}
}
resource "aws_subnet" "public" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.1.0/24"
availability_zone = "us-west-2a"
map_public_ip_on_launch = true
tags = {
Name = "public-subnet"
}
}
resource "aws_subnet" "private" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.2.0/24"
availability_zone = "us-west-2b"
tags = {
Name = "private-subnet"
}
}
resource "aws_security_group" "web" {
name = "web-sg"
description = "Allow HTTP and SSH traffic"
vpc_id = aws_vpc.main.id
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_s3_bucket" "data" {
bucket = "my-data-bucket"
acl = "private"
versioning {
enabled = true
}
tags = {
Name = "data-bucket"
}
}
resource "aws_db_instance" "default" {
allocated_storage = 20
storage_type = "gp2"
engine = "mysql"
engine_version = "5.7"
instance_class = "db.t2.micro"
name = "mydb"
username = "admin"
password = "password"
parameter_group_name = "default.mysql5.7"
skip_final_snapshot = true
vpc_security_group_ids = [aws_security_group.db.id]
db_subnet_group_name = aws_db_subnet_group.default.name
}
Terraformは、作成したリソースの状態を状態ファイル(通常はterraform.tfstate
)に保存します。この状態ファイルは、Terraformがリソースの現在の状態を追跡し、変更を計画するために使用されます。
チーム開発やCI/CDパイプラインでは、状態ファイルをリモートで管理することが推奨されます。AWSでは、S3バケットとDynamoDBを使用して状態ファイルを管理することができます。
terraform {
backend "s3" {
bucket = "terraform-state-bucket"
key = "terraform.tfstate"
region = "us-west-2"
encrypt = true
dynamodb_table = "terraform-locks"
}
}
resource "aws_dynamodb_table" "terraform_locks" {
name = "terraform-locks"
billing_mode = "PAY_PER_REQUEST"
hash_key = "LockID"
attribute {
name = "LockID"
type = "S"
}
}
terraform state list
terraform state show aws_instance.web
terraform state rm aws_instance.web
terraform import aws_instance.web i-1234567890abcdef0
Terraformモジュールは、再利用可能なインフラストラクチャコンポーネントを作成するための仕組みです。モジュールを使用することで、コードの重複を減らし、ベストプラクティスを共有することができます。
modules/
├── vpc/
│ ├── main.tf
│ ├── variables.tf
│ └── outputs.tf
└── web-server/
├── main.tf
├── variables.tf
└── outputs.tf
resource "aws_vpc" "this" {
cidr_block = var.cidr_block
enable_dns_support = true
enable_dns_hostnames = true
tags = {
Name = "${var.environment}-vpc"
Environment = var.environment
}
}
resource "aws_subnet" "public" {
vpc_id = aws_vpc.this.id
cidr_block = var.public_subnet_cidr
availability_zone = var.availability_zone
map_public_ip_on_launch = true
tags = {
Name = "${var.environment}-public-subnet"
Environment = var.environment
}
}
variable "cidr_block" {
description = "CIDR block for the VPC"
type = string
}
variable "public_subnet_cidr" {
description = "CIDR block for the public subnet"
type = string
}
variable "availability_zone" {
description = "Availability zone for the subnet"
type = string
}
variable "environment" {
description = "Deployment environment"
type = string
}
output "vpc_id" {
description = "The ID of the VPC"
value = aws_vpc.this.id
}
output "public_subnet_id" {
description = "The ID of the public subnet"
value = aws_subnet.public.id
}
module "vpc" {
source = "./modules/vpc"
cidr_block = "10.0.0.0/16"
public_subnet_cidr = "10.0.1.0/24"
availability_zone = "us-west-2a"
environment = "dev"
}
module "web_server" {
source = "./modules/web-server"
vpc_id = module.vpc.vpc_id
subnet_id = module.vpc.public_subnet_id
instance_type = "t2.micro"
environment = "dev"
}
terraform plan
の出力を確認するterraform fmt
を使用してコードを整形するterraform validate
を使用して構成を検証するTerraformとAWS CloudFormationは、どちらもインフラストラクチャ as コード(IaC)ツールですが、いくつかの重要な違いがあります。
特徴 | Terraform | CloudFormation |
---|---|---|
プロバイダー | マルチクラウド(AWS、Azure、GCP、その他) | AWSのみ |
言語 | HCL(HashiCorp Configuration Language) | YAML/JSON |
状態管理 | 状態ファイルを管理する必要あり | AWSが管理 |
変更検出 | 計画フェーズ(terraform plan) | ドリフト検出 |
リソースのサポート | 多くのプロバイダーのリソースをサポート | AWSリソースの包括的なサポート |
モジュール化 | Terraformモジュール | ネスト化されたスタック |
コミュニティ | 幅広いオープンソースコミュニティ | AWSコミュニティ |
統合 | 多くのサードパーティツールとの統合 | AWSサービスとの緊密な統合 |
学習曲線 | 中程度 | 比較的緩やか |
ロールバック | 手動(状態を使用) | 自動(エラー時) |
HashiCorpは、Terraformの商用版としてTerraform CloudとTerraform Enterpriseを提供しています。これらのサービスは、チームでのTerraformの使用を容易にするための追加機能を提供します。
Terraformは、AWSを含む多くのクラウドプロバイダーのインフラストラクチャをコードとして定義、プロビジョニング、管理するための強力なツールです。HCL(HashiCorp Configuration Language)を使用した宣言的な構文、多くのプロバイダーのサポート、モジュール化による再利用性など、多くの利点を提供します。
Terraformの主な利点は以下の通りです:
Terraformを効果的に活用するには、状態ファイルの適切な管理、モジュール化によるコードの再利用、変数の活用、セキュリティのベストプラクティスの適用などが重要です。また、プロジェクトの要件に応じて、CloudFormationなどの他のIaCツールと比較して、最適なツールを選択することも重要です。