Terraformとは?

SHARE:

Terraform は、HashiCorp によって開発されたオープンソースの Infrastructure as Code(IaC) ツールです。

Terraform を使用すると、リソースやインフラストラクチャをシンプルで読みやすい構成ファイルで定義し、インフラ全体のライフサイクルを自動化できます。

公式ドキュメントによると、Terraform は次のように説明されています:

Terraform は、クラウドおよびオンプレミスのリソースを安全かつ効率的に構築、変更、バージョン管理できる Infrastructure as Code ツールです。

Terraformアーキテクチャ (出典: Hashicorp)

Terraform allows us to work with different providers. In the following example, we create a main.tf file with a configuration to create a simple AWS EC2.

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.16"
    }
  }
  required_version = ">= 1.2.0"
}
provider "aws" {
  region  = "us-west-2"
}
resource "aws_instance" "app_server" {
  ami           = "ami-830c94e3"
  instance_type = "t2.micro"
  tags = {
    Name = "ExampleAppServerInstance"
  }
}Code language: JavaScript (javascript)

インフラコードが準備できたら、プロビジョニングを行うために推奨されるいくつかの手順があります。

Terraform プロセス (出典: Hashicorp)

依存関係ロックファイルを初期化するために、最初の依存関係を選択するには、次のコマンドを実行します。

terraform init
Initializing the backend...
Initializing provider plugins...
- Finding hashicorp/aws versions matching "~> 4.16"...
- Installing hashicorp/aws v4.58.0...
- Installed hashicorp/aws v4.58.0 (signed by HashiCorp)
Terraform has been successfully initialized!Code language: JavaScript (javascript)

この EC2 をプロビジョニングする場合は、まず terraform plan を実行して実行計画を作成し、必要な要件がそろっているか確認するのが望ましいです。以下は、現在の状態に対して実行した場合の挙動です。

terraform plan
Error: configuring Terraform AWS Provider: no valid credential sources for Terraform AWS Provider found.

現在使用しているプロバイダー(AWS)向けの有効な認証情報がプロビジョニングされていません。そのため、まず認証情報を用意する必要があります。これは環境変数で設定できます:

export AWS_ACCESS_KEY_ID=<Insert your ACCESS_KEY>
export AWS_SECRET_ACCESS_KEY=<Insert your SECRET_KEY>Code language: HTML, XML (xml)

これで問題なく terraform apply コマンドを実行でき、main.tf ドキュメントで指定したパラメータに基づいて EC2 マシンがプロビジョニングされます。

これは Terraform の基本的な入門例ですが、以下のトピックについては公式ドキュメントでさらに詳しく学ぶことができます:

  • Terraformのバージョン管理
  • Terraform マニフェストのテスト
  • モジュールを再利用可能にするための変数の使用
  • 環境変数の活用
  • Terraform のトラブルシューティング(言語エラーの対処)

Terraformのバージョン管理

常に Terraform のバージョン管理を行い、Terraform マニフェストが適切な Terraform バージョンと互換性を持つようにしてください。セキュリティの観点からも、これにより互換性の問題を回避し、すべての環境でインフラコードの一貫性を確保することができます。

#!/bin/bash

# Set the path to your Terraform code
TERRAFORM_PATH="./my-terraform-code"

# Set the required Terraform version
TERRAFORM_VERSION="1.0.11"

# Check if the required Terraform version is installed
if ! command -v terraform &> /dev/null
then
    echo "Terraform is not installed. 
          Please install the Terraform version $TERRAFORM_VERSION and try again."
    exit
fi

# Check the installed Terraform version
INSTALLED_VERSION=$(terraform version | head -n 1 | cut -d ' ' -f 2)

# Compare the installed version with the required version
if [ "$INSTALLED_VERSION" != "$TERRAFORM_VERSION" ]
then
    echo "Terraform version $TERRAFORM_VERSION is required but version $INSTALLED_VERSION
          is installed. Please install the required version and try again."
    exit
fi

# Run Terraform commands on the specified path
terraform plan "$TERRAFORM_PATH"
Code language: PHP (php)

スクリプトを保存したら、その保存先ディレクトリに移動し、ターミナルで次のコマンドを実行してスクリプトを起動します。

sh my-script.shCode language: CSS (css)

このスクリプトを実行すると、インストールされている Terraform のバージョンをスクリプト内で指定された必要なバージョンと照合します。インストールされているバージョンが一致しない場合、スクリプトはエラーメッセージを出力して終了します。一方、一致している場合はスクリプトが続行され、指定されたパス上で Terraform コマンドを実行します。

また、Flora は Terraform マニフェストの管理とセキュリティ強化に役立つ、優れたオープンソースツールです。Flora を使用することで、Terraform のセキュリティをさらに向上させることができます。

Terraform マニフェストを独立した Git リポジトリに保存することで、不正アクセスの防止変更履歴の追跡・監査 を容易にします。さらに、Git のアクセス制御機能を活用して権限を管理し、認可されたユーザーのみがインフラコードを変更できるようにすることが可能です。

以下は、Checkov を利用してポリシーを強制し、Flora が Terraform セキュリティを向上させる仕組みの例です。

1. Flora と Checkov のインストール

まず、Flora と Checkov をインストールする必要があります。Flora は pip を使用してインストールでき、Checkov はパッケージマネージャーまたは GitHub から直接インストールできます。

pip install floraapt install checkov

2. 新しい Flora リポジトリを初期化

次に、Terraform マニフェストを保存するための新しい Flora リポジトリを初期化します。Flora は新しい Git リポジトリを作成し、Terraform で使用できるように自動的に構成します。

flora init my-infrastructurecd my-infrastructure

3. Terraform マニフェストを Flora リポジトリに追加

次に、Terraform マニフェストを Flora リポジトリに追加します。マニフェストはリポジトリに直接追加することも、Terraform モジュールを使用して追加することもできます。

flora add terraform/manifests

4. Checkov をコミット時に実行するように設定

次に、Terraform マニフェストに変更が加えられた際に、Checkov が自動的に実行されるように設定します。これにより、セキュリティポリシーの適用を自動化し、インフラコードに問題が持ち込まれるのを防ぐことができます。

flora hooks add --name checkov --cmd "checkov -d ./terraform/manifests" --on commitCode language: JavaScript (javascript)

5. Flora repoをテスト

最後に、Flora リポジトリをテストして、Checkov が正しく動作していることを確認します。Terraform マニフェストのいずれかに変更を加えてコミットすると、Checkov が自動的に実行され、ポリシー違反があれば検出されるはずです。

Failed checks: CKV_AWS_19: "Ensure the S3 bucket has versioning enabled"Code language: JavaScript (javascript)

この例では、Checkov は すべての S3 バケットでバージョニングを有効にする というポリシーを適用するために使用されています。もしバージョニングが有効になっていない場合、Checkov はその問題を検出し、コミットが実行されないようにします。

また、常に Terraform のバージョン管理 を行うことで、Terraform マニフェストが正しい Terraform バージョンと互換性を保つことができ、互換性に関する問題を回避できます。これにより、すべての環境でインフラコードの一貫性を維持し、互換性の問題に起因するセキュリティリスクを軽減することができます。

Terraform マニフェストのテスト

マニフェストをテストすることで、エラーを早期に発見し、インフラコードが期待どおりに動作していることを確認できます。Terratest のようなツールを使用すれば、テストを自動化し、Terraform マニフェストの動作を効率的に検証できます。

#!/bin/bash

# Set the path to your Terraform code
TERRAFORM_PATH="./my-terraform-code"

# Set the path to your Terratest code
TERRATEST_PATH="./my-terratest-code"

# Run Terraform init on the specified path
terraform init "$TERRAFORM_PATH"

# Run Terraform apply on the specified path
terraform apply -auto-approve "$TERRAFORM_PATH"

# Run Terratest on the specified path
go test -v "$TERRATEST_PATH"Code language: PHP (php)

注意:

これらのスクリプトは、Terraform CLI と Terratest がマシンにインストールされ、システムの PATH 環境変数に追加されていることを前提としています。Terratest は HashiCorp Vault と同様にサードパーティ製のツールであるため、ツールに関して懸念がある場合は公式ドキュメント(terratest.gruntwork.io)を確認してください。

スクリプトを保存したら、その保存先ディレクトリに移動し、ターミナルで次のコマンドを実行してスクリプトを起動します。

sh my-script.shCode language: CSS (css)

これによりスクリプトが実行され、Terraform コマンドを通じてインフラコードが適用され、その後 Terratest によってテストが実行されます。Terratest は、インフラコード向けの自動テストを容易にする Go 言語のライブラリ です。Terraform マニフェストを Terratest でテストすることで、エラーを検出し、インフラコードの安全性と信頼性を確保することができます。

モジュールを再利用可能にするために変数を使用

モジュールを再利用可能にするためには、変数(variables) を活用しましょう。これにより、たとえば「シークレット」値などをハードコーディングせずに済み、異なる環境に応じてモジュールを柔軟にカスタマイズできるようになります。環境変数 または 入力変数(input variables) を使用して値を Terraform モジュールに渡すことで、シークレットやその他の機密情報をより安全かつ簡単に管理することができます。

# variables.tf
variable "region" {
  type    = string
  default = "eu-west-1"
}

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

variable "ami" {
  type    = string
  default = "ami-0c55b159cbfafe1f0"
}

# main.tf
provider "aws" {
  region = var.region
}

resource "aws_instance" "example" {
  ami           = var.ami`
  instance_type = var.instance_type
  # ...
}Code language: PHP (php)

上記の例では、variables.tf ファイル内で 3 つの変数を定義しました。これらの変数は、main.tf ファイル内で aws_instance リソースを構成するために使用されています。

  • region(リージョン)
  • instance_type(インスタンスタイプ)
  • ami(Amazon Machine Image)

環境変数の使用

変数を使用することで、値をハードコーディングせずに同じモジュールを複数の環境で再利用できます。たとえば、異なる環境でこのモジュールを適用する際に、変数に異なる値を渡すことで、環境ごとの設定を簡単に切り替えることができます。

module "example_instance" {
  source = "./example-instance"

  region        = "eu-west-1"
  instance_type = "t2.small"
  ami           = "ami-03d315ad33b9d49c4"
}Code language: JavaScript (javascript)

上記の例では、module ブロックを使用して example-instance モジュールを参照し、region、instance_type、ami の各変数に値を渡しています。このように 入力変数(input variables) を利用することで、Terraform 構成ファイル内でシークレットやその他の機密情報を直接公開することなく、安全に管理できます。

これらの値は 環境変数 を通じて渡すこともできますし、VaultAWS Secrets Manager のようなシークレット管理システムを利用して、動的に取得することも可能です。

Terraform のトラブルシューティング — 言語エラー

コードの構文を確認するには、terraform validate のような リンター(linter) を使用しましょう。これにより、インフラに変更を適用する前にエラーを検出できます。セキュリティの観点からも、リンティングは コード標準やベストプラクティスの遵守 を促し、安全で一貫性のある Terraform コードの維持に役立ちます。

#!/bin/bash

# Set the path to your Terraform code
TERRAFORM_PATH="./my-terraform-code"

# Run Terraform validate on the specified path
terraform validate "$TERRAFORM_PATH"Code language: PHP (php)

このスクリプトは、Terraform CLI がマシンにインストールされ、システムの PATH 環境変数に追加されていることを前提としています。スクリプトを保存したら、その保存先ディレクトリに移動し、ターミナルで次のコマンドを実行してスクリプトを起動します。

sh my-script.shCode language: CSS (css)

または、スクリプトに実行権限を付与し、新しい実行ファイルとして実行することもできます。

Chmod +x my-script.sh
./my-script.sh

このスクリプトを実行すると、Terraform コードに対して terraform validate が実行されます。コードに構文エラーや問題がある場合、Terraform はエラーメッセージを出力して該当箇所を示します。このプロセスを利用することで、インフラに変更を適用する前にエラーを検出し、問題を未然に防ぐことができます。

まとめ

始めるのは難しくありませんが、熟練するには時間と経験が必要です。ここで紹介した推奨事項に従うことで、Terraform を使ってコードからインフラをプロビジョニングする作業がより簡単になるでしょう。さらにセキュリティについて学びたい場合は、Terraform セキュリティベストプラクティス を参照することをおすすめします。