🐾

Terraformの基本

2024/01/28に公開

概要

Terraformを使用する機会があったので学習して、ついでにその内容をまとました。メモ的な記事ですがTerraformを初めて使用する方々にとって参考になればと思っています。

この記事を読む理由

  • Terraformの概要を把握することができる
  • 基本的な文法を知ることができる
  • 既に構築されているプロジェクトのコードの内容が理解できるようになる

この記事に記載されていないこと

Terraformのインストール手順などは記載していません。

Terraformとは?

TerraformはIaC(Infrastructure as Code)ツールの一つです。
名前の通りAWSなどの各クラウドベンダーが公開しているインフラ管理用のAPIをコードから呼び出して、インフラリソースの作成、変更、削除などができます。
AWS以外にもGCPやAzureなど、様々なクラウドベンダーに対応しています。

コードで管理すると何が嬉しいの?

  • 手順書が不要
    • ブラウザ画面での操作の場合、その内容を手順書にまとめる必要がありますが、コードがその役割を果たします。
  • オペレーションミスのリスクを削減
    • ブラウザ上で作業する際、誤操作のリスクがありますが、複数人でコードをレビューすることで操作のミスを減らせます。
  • 簡単に環境を再現
    • 同じコードを使用して環境を繰り返しデプロイできるため、開発、テスト、本番環境間の不一致を減らせます。

基本的なコマンド

terraform init

Terraformプロジェクトの初期化を行います。はじめに必ず実行する必要があります。

terraform plan

変更内容を表示します。コードを追加、変更した場合はこのコマンドを実行して内容に問題がないかを確認します。

terraform apply

実際のリソースの変更がこのコマンドによって行われます。

terraform destroy

管理されているリソースをすべて破棄します。

基本的な構文

Providers

AWSを利用するための定義をします。

以下の例ではAWS、東京リージョン(ap-northeast-1)を指定しています。

provider "aws" {
  region = "ap-northeast-1"
}

Resources

具体的なインフラストラクチャーのコンポーネント(EC2インスタンス、セキュリティグループ、VPC等)を表します。

以下はEC2インスタンスを構築しています。

resource "aws_instance" "this" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.micro"
}
  • aws_instance -> リソースの種類
  • this -> Terraform内で使うリソースの名前
  • ブロック内 -> 引数(リソースの設定)

Local Values

モジュール内に閉じて使える変数です。モジュール内でのローカル変数のようなものです。

locals {
  project_name = "my-project"
}

Input Variables

変数を使用すると、コードの再利用性を高め、ハードコードされた値を避けることができます。具体的にはterraform apply実行時に対話的に入力することなどが可能です。

variable "allow_ssh" {
  type    = bool
  default = false
}

Output Values

terraform applyした際に、ターミナルに出力されます。作成されたリソースの属性(サーバーのIPアドレスなど)を外部に公開するときなどに便利です。

output "instance_ip_addr" {
  value = aws_instance.this.public_ip
}

Data Sources

外部データを読み取ることができます。

以下の例では最新のAmazon Linux AMIのIDを検索します。名前フィルタを使用して特定の種類のAMI(この場合は amzn2-ami-hvm-*-x86_64-gp2)を指定します。

data "aws_ami" "latest_amazon_linux" {
  most_recent = true
  owners      = ["amazon"]

  filter {
    name   = "name"
    values = ["amzn2-ami-hvm-*-x86_64-gp2"]
  }
}

locals {
  ami_id = data.aws_ami.latest_amazon_linux.id
}

Modules

複数のリソースをまとめたものです。

ルートモジュールと子モジュール

.tfファイルのある作業ディレクトリのことを「ルートモジュール」と呼称します。そしてルートモジュールから呼び出されるモジュールが「子モジュール」となります。

./modules/vpcのモジュールを参照する。

module "vpc" {
  source = "./modules/vpc"
}

tfstateファイルの管理

Terraformはterraform.tfstateという状態ファイルを使用して、管理しているリソースの現在の状態を追跡します。これにより、Terraformは実際のインフラストラクチャーとコード間の差分を認識し、適切な変更を適用できます。

特に設定していない場合はterraform applyを実行したマシン上にtfstateファイルが保存されます。しかし、terraform applyなどの操作を行う人が複数人いる場合、最新のtfstateファイルを共有する必要があります。
以下の例では、AWSのS3を使用してTerraformの状態ファイルを管理します。

terraform {
  backend "s3" {
    bucket = "terraform-s3-test-my-name"
    key    = "terraform.tfstate"
    region = "ap-northeast-1"
  }
}

ディレクトリ構成

一般的なTerraformのディレクトリ構成は以下のようになります。

├── envs/ # 環境別の設定
│    ├── dev/
│    ├── prod/
│    └── stg/
├── module/ # 再利用可能なTerraformモジュール
│    ├── ec2/
│    ├── vpc/

この構成は、異なる環境(開発、本番、ステージング)の設定を分離し、同時に一般的なリソース(EC2インスタンス、VPCなど)をモジュール化して再利用を容易にするために使われます。これにより、コードの重複を避け、メンテナンスの効率を高めることができます。

Discussion