AWSにIaC環境をTerraformを使って構築してみた(基礎)


はじめに

最近、IaC(Infrastructure as Codeの略)でシステム構築を行うことが主流になってきています。
IaCとはその名の通り、システムインフラをコードで管理しようというもので、リソースの全体像をコードで把握したり、そのソースで自動構築を行うことで短時間で多くのサーバを構築できるといったメリットがあります。
以前からこれらを実現するために、Ansible、chef、puppetといったツールが使われていましたが、今回は、昨今あたり前となっているAWS環境でIaC環境を実現するためにTerraformを使用します。

TerraformはクラウドリソースそのものをIaCで構築できるところがメリットです。AWSであればCloudFormationが同じ役割を担いますが、AWSやGCPなどマルチクラウドで使用できる汎用性に期待して、今回はTerraformを採用します。

システム構成

システム構成は以下の図となります。
今回は、CodeCommitにリソース情報をプッシュしたらAWSのVPCが自動で作成される環境を構築してみましょう。

CodeCommit

ソースリポジトリを指します。有名なところで言うとGitlab、GithubのAWS版になります。
ここに様々なソースを置きます。

EventBridge

旧CloudWatch Eventのことで、AWSのさまざまなイベントを拾って、そのイベントに対してさらに何かイベントを実行することが可能になります。
今回はCodeCommitにプッシュされたイベントを検知して後続のCodeBuildを実行するように仕込みます。

CodeBuild

今回のメインです。ビルドを行うサービスで、Terraformを実行する箇所になります。

CodePipeline

CodeXXシリーズを連結させるのに便利なサービスです。

VPC

Virtual Private Cloudの略です。今回IaCで作成するリソースです。

構築してみる

CodeCommit

AWSの管理コンソールからCodeCommitを検索します。リポジトリを任意の名前で作成してください。
リポジトリの作成が完了したら、ファイルの作成を使って、以下の3点セットを用意します。

No ファイル名 説明
1 buildspec.yml CodeBuildの実行定義ファイルです。
2 provider.tf Terraformで読まれるファイル(.tf)です。AWSのバージョンなど、configファイルのような立ち位置です。
3 resource.tf Terraformで読まれるファイル(.tf)です。このファイルがIaCの根幹となるリソースを定義したファイルです。

.tfファイルについて
Terraformはフォルダ内の拡張子が.tfのファイルを読み込む仕様のため、「2. provider.tf」と「3. resource.tf」は同じファイルに記載してもかまいませんし、「3. resource.tf」をリソースに応じてファイルを分割して管理しやすくするのもOKです。

buildspec.yml
version: 0.2
phases:
  install:
    runtime-versions:
      docker: 18
    commands:
      - ls -la
      - yum install unzip -y
      - wget https://releases.hashicorp.com/terraform/0.12.19/terraform_0.12.19_linux_amd64.zip
      - unzip terraform_0.12.19_linux_amd64.zip
      - mv terraform /usr/local/bin/
  pre_build:
    commands:
      - terraform init -input=false
      - terraform plan -input=false
  build:
    commands:
      - echo "build phase"      
      - terraform apply -input=false -auto-approve
  post_build:
    commands:
      - echo "post phase"
provider.tf
terraform {
  required_version = ">= 0.12.0"
  backend "s3" {
    encrypt        = false
    bucket         = "{YOUR-BUCKET-NAME}"
    key            = "terraform/terraform.tfstate"
    region         = "ap-northeast-1"
  }
}
provider "aws" {
  region  = "ap-northeast-1"
  version = "~> 3.37"
}

bucketについて
このbucketはS3を指しています。Terraformでは現在のTerraformの管理状態をterraform.tfstateというファイルに記載して管理してあります。どこに保存していてもアクセスできれば自由ですが、可用性の高いS3に保存します。そのため、S3 bucketを事前に作成し、terraformというフォルダを作成しておいてください。

resource.tf
resource "aws_vpc" "vpc" {
  cidr_block = "192.168.0.0/16"
  tags = {
    Name = "YOUR-VPC-NAME"
  }
}
EventBridge

EventBridgeはCodePipelineで自動的に設定してくれるので、個別で作成はしません。

CodeBuild

マネジメントコンソールでCodeBuildのページへアクセスします。
「ビルドプロジェクトを作成する」からビルドプロジェクトを作成します。
作成するにあたって必要な設定は以下です。

  • プロジェクト名:自身で決めた任意のプロジェクト名です。
  • ソースプロバイダ:「AWS CodeCommit」を選択します。
  • リポジトリ:自身で作成したCodeCommitのリポジトリ名を指定します。
  • リファレンスタイプ:「ブランチ」を選択
  • ブランチ:「main」を選択
  • 環境イメージ:「マネージド型イメージ」を選択
  • オペレーティングシステム:「Amazon Linux2」を選択
  • ランタイム:Standardを選択
  • イメージ:選べる中で「x86_64」である最新のもの
  • サービスロール:新しいサービスロール
  • ロール名:任意の名称で記載します。
  • ビルド仕様:「buildspecファイルを使用する」を選択
  • CloudWatch Logs-オプショナル:チェック有
CodePipeline

マネジメントコンソールでCodePipelineのページへアクセスします。
「パイプラインを作成する」からパイプラインを作成します。
作成するにあたって必要な設定は以下です。

  • パイプライン名:任意の名称を設定します。
  • サービスロール:「新しいサービスロール」を選択
  • ロール名:任意のロール名を設定します。
  • パイプラインでのロール使用許可:チェック有
    ↓次のページへ
  • ソース:「AWS CodeCommit」を選択
  • リポジトリ名:自身でCodeCommitで作成したリポジトリ名
  • ブランチ名:「main」を選択
  • 検出オプションを変更する:「Amazon CloudWatch Events(推奨)」を選択
  • 出力アーティファクト形式:「CodePipeline のデフォルト」を選択
    ↓次のページへ
  • プロバイダーを構築する:「AWS CodeBuild」を選択
  • リージョン:アジアパシフィック(東京)
  • プロジェクト名:自身で作成したCodeBuildプロジェクト名を選択
  • ビルドタイプ:「単一ビルド」を選択
    ↓次のページへ
  • デプロイプロバイダを選択せずに「導入段階をスキップ」を選択
    ↓次のページへ
    内容を見ておかしなところがないか確認して「パイプラインを作成する」をクリック

補足
CodePipelineでCodeCommit及びCodeBuildを指定してパイプラインを作成することで、
CodeCommitのソース変化のイベントを探知してCodeBuildのプロジェクトを実行するEventBridgeの設定を勝手に行ってくれます。

  実際に動かしてみる

自身で作成したCodeCommitのリポジトリの中からresource.tfを編集してみましょう。コメント追加でもなんでもいいです。リポジトリにプッシュすると、そのプッシュイベントを元に、CodeBuildのビルドが実行され、VPCリソースが作成されているはずです。