Terraformを使ってみる(AWS)

こんにちは、クラウドCoEの城前です。
最近プロジェクトで、Terraformを利用しAWSを構築する機会があったため、今回のテーマはTerraformにしたいと思います。

備忘録も兼ねてTerraformを利用するための環境のSetUP方法や基本的な使い方について纏めてみました。

本コラムでやること

  • TerraformのSetUP ※今回はOS:ubuntu 18.04の環境で行います
  • Terraformの基本構文について説明します
  • 実際にTerraformでAWS内にVPCを作成し、作成した環境を削除するところまで行います。

TerraformのSetUP

今回はOS:ubuntu 18.04でTerraformの環境のSetUPを行いたいと思います。

まずはLinuxbrewのインストールと環境変数の設定を行います。

Linuxbrewとはこのあと説明するtfenvをインストールするために必要なmacOS向けのパッケージ管理システム「Homebrew」のLinux向けクローンとなります。

・Linuxbrewのインストール

$ sh -c "$(curl -fsSL https://raw.githubusercontent.com/Linuxbrew/install/master/install.sh)"

・環境変数設定

$ test -d ~/.linuxbrew && eval $(~/.linuxbrew/bin/brew shellenv)
$ test -d /home/linuxbrew/.linuxbrew && eval $(/home/linuxbrew/.linuxbrew/bin/brew shellenv)

次にtfenvのインストールを行います。

tfenvとはTerraformのバージョン管理を簡単に行えるツールです。

Terraformはバージョンの変化が早いツールです。そのため直接Terraformをインストールしてしまうとバージョンの変化に対応しにくいため、今回はtfenvを利用します。

・tfenvインストール

$ brew install tfenv

・利用バージョンの確認

$ tfenv list-remote | head
0.14.3
0.14.2
0.14.1
0.14.0
0.14.0-rc1
0.14.0-beta2
0.14.0-beta1
0.14.0-alpha20201007
0.14.0-alpha20200923
0.14.0-alpha20200910

今回は現時点で最新の0.14.3をインストールしてみます。

$ tfenv install 0.14.3

次にuseコマンドで利用するバージョンを指定します。

$ tfenv use 0.14.3
Switching default version to v0.14.3
Switching completed

続いてlistコマンドで確認します。先頭に「*」がついているバージョンが現在選択されているバージョンになります。

$ tfenv list
* 0.14.3 (set by /home/linuxbrew/.linuxbrew/Cellar/tfenv/2.0.0/version)

これでTerraformの設定は完了です。続けてAWSへのアクセス設定を行います。

まずは、aws-vaultのインストールをします。aws-vaultとは、アクセスキー等のAWSの認証情報をセキュアに保管できてかつMFA認証も簡単に行える便利なツールです。

$ brew install aws-vault

もし、aws-cliがインストールされていない場合は以下サイトを参考にインストールを行ってください。

https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/install-cliv2-linux.html

続いてAWSアカウント内で払い出したIAMのアクセスキー、シークレットキーの情報をaws-vaultに登録します。

「tfuser」はaws-vaultに登録する際の任意の名称となります。

$ aws-vault add --backend=file --add-config tfuser
Enter Access Key Id: XXXXXXXXXXXXXXX
Enter Secret Key: XXXXXXXXXXXXXXXXXXXXXXXXX

$HOME/.aws/configファイルを以下のように編集します。

「123456789012」の箇所はAWSアカウントID、「user1」は払いだしたIAMユーザ名となります。

[default]
region=ap-northeast-1
output=json

[profile tfuser]
mfa_serial=arn:aws:iam::123456789012:mfa/user1

これでAWS環境へもアクセスが行えるようになっているはずです。

例えばS3バケットの一覧を表示させたい場合は以下のようにコマンドの先頭に「aws-vault exec –backend=file tfuser –」を付与して実行をしてください。

実行の際には設定したパスワードとMFA認証コードを求められます。入力後正常にS3バケットの一覧が取得できていれば成功です。

$ aws-vault exec --backend=file tfuser -- aws s3 ls

Terraformの基本構文説明

Terraformはカレントディレクトリにある.tfファイルを全て読み込みます。
つまり1つのファイルに記述しても処理単位で複数ファイルに記述しても全て実行されます。
今回は以下2ファイルを作成してAWS上にVPCを作成します。それぞれのファイルについて説明していきます。

$ tree
.
├── main.tf
└── vpc.tf

まず、main.tfですが以下のように「provider」というブロックタイプが指定されています。

providerとはAWS/GCP/Azureのようなクラウド、オンプレ、SaaSなど、どのインフラを使うかの宣言を行います。今回はAWS上に構築するので「aws」としています。さらにproviderの設定項目としてregionを指定しています。今回は東京リージョンに作成をするので「ap-northeast-1」としています。

・main.tf

######################################################################
# provider 設定
######################################################################
provider "aws" {
  region = "ap-northeast-1"
}

次に、vpc.tfの場合ですと「resource」というブロックタイプが登場します。

resourceとはインフラ上へ作成するリソースを定義する場合に使います。

「aws_vpc」は構築対象のリソースで対象のprovider(AWS/GCP/Azure等)によってあらかじめ定義されています。
「vpc」はTerraform内のリソースの名称となり同一ディレクトリ内でユニークである必要があります。
「cidr_block」は定義したリソースの設定項目で「192.168.0.0/16」がその設定内容となります。設定項目は構築対象のリソースによって異なります。

・vpc.tf

######################################################################
# VPC 設定
######################################################################

resource "aws_vpc" "vpc" {
  # ネットワークの範囲を指定
  cidr_block = "192.168.0.0/16"
  # タグを設定
  tags = {
    Name = "terraform-vpc"
  }
}

指定できるブロックタイプは本コラムで紹介したprovider、resource以外にもたくさんありますので、もし興味があれば調べてみてください。

実際に構築してみる

Terraform用に任意のディレクトリを作成し、そのディレクトリ配下に.tfファイルを用意します。

$ mkdir terraform
$ cd terraform
$ vi main.tf
以下のようにファイルを編集
######################################################################
# provider 設定
######################################################################
provider "aws" {
  region = "ap-northeast-1"
}

$ vi vpc.tf
以下のようにファイルを編集
######################################################################
# VPC 設定
######################################################################
resource "aws_vpc" "vpc" {
  # ネットワークの範囲を指定
  cidr_block = "192.168.0.0/16"
  # タグを設定
  tags = {
    Name = "terraform-vpc"
  }
}

Terraformの初回起動時はterraform initで初期化を行います。

terraform init を実行すると.tf ファイルで利用している plugin(先述の例でいうと aws provider など)のダウンロード処理などが走ります。

$ aws-vault exec --backend=file tfuser -- terraform init

以下のメッセージが出力されれば正常に初期化が行われています。

Terraform has been successfully initialized!

初期化後.terraform配下にダウンロードされたファイル群が配置されます。

$ ls .terraform
providers

初期化後はplanコマンドで事前に実行内容を確認することができます。まずは.tfファイルに記述したコードの実行テストを行います。

実行すると以下のように設定値が出力されます。

$ aws-vault exec --backend=file tfuser -- terraform plan

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # aws_vpc.vpc will be created
  + resource "aws_vpc" "vpc" {
      + arn                              = (known after apply)
      + assign_generated_ipv6_cidr_block = false
      + cidr_block                       = "192.168.0.0/16"
      + default_network_acl_id           = (known after apply)
      + default_route_table_id           = (known after apply)
      + default_security_group_id        = (known after apply)
      + dhcp_options_id                  = (known after apply)
      + enable_classiclink               = (known after apply)
      + enable_classiclink_dns_support   = (known after apply)
      + enable_dns_hostnames             = (known after apply)
      + enable_dns_support               = true
      + id                               = (known after apply)
      + instance_tenancy                 = "default"
      + ipv6_association_id              = (known after apply)
      + ipv6_cidr_block                  = (known after apply)
      + main_route_table_id              = (known after apply)
      + owner_id                         = (known after apply)
      + tags                             = {
          + "Name" = "terraform-vpc"
        }
    }

Plan: 1 to add, 0 to change, 0 to destroy.

------------------------------------------------------------------------

Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.

上記の確認で問題が無ければいよいよVPCの作成です。

以下のようにapllyコマンドを実行し、「Enter a value:」と聞かれるので「yes」と返します。

$ aws-vault exec --backend=file tfuser -- terraform apply

Enter a value:yes

aws_vpc.vpc: Creating...
aws_vpc.vpc: Creation complete after 1s [id=vpc-07c3c9fff342898b7]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

AWSコンソール画面からもVPCが作成されていることが確認できます。

また、state listコマンドで構築したリソースの確認が行えます。さらに以下のようにstate showコマンドで作成したリソースの設定値を確認することも可能です。

$ aws-vault exec --backend=file tfuser -- terraform state list
aws_vpc.vpc
$ aws-vault exec --backend=file tfuser -- terraform state show aws_vpc.vpc
  aws_vpc.vpc:
resource "aws_vpc" "vpc" {
    arn                              = "arn:aws:ec2:ap-northeast-1:897017069630:vpc/vpc-07c3c9fff342898b7"
    assign_generated_ipv6_cidr_block = false
    cidr_block                       = "192.168.0.0/16"
    default_network_acl_id           = "acl-082b9838c62acb180"
    default_route_table_id           = "rtb-0958dcf3c69ac4244"
    default_security_group_id        = "sg-0da6b3b1f2441c2bc"
    dhcp_options_id                  = "dopt-e4d8d583"
    enable_classiclink               = false
    enable_classiclink_dns_support   = false
    enable_dns_hostnames             = false
    enable_dns_support               = true
    id                               = "vpc-07c3c9fff342898b7"
    instance_tenancy                 = "default"
    main_route_table_id              = "rtb-0958dcf3c69ac4244"
    owner_id                         = "123456789012"
    tags                             = {
        "Name" = "terraform-vpc"
    }
}

最後に作成したVPCをdestroyコマンドで削除します。

まずは削除対象を確認するために作成時と同様にplanコマンドで確認をおこないます。

$ aws-vault exec --backend=file tfuser -- terraform plan -destroy

削除対象を確認し問題がなければplanを外してdestroyコマンドを実行します。

本当に削除していいか確認を求められるので「yes」と入力しEnterを押下します。

$ aws-vault exec --backend=file tfuser -- terraform destroy
Do you really want to destroy?
  Terraform will delete all your managed infrastructure.
  There is no undo. Only 'yes' will be accepted to confirm.
Enter a value: yes

実行後、先程のAWSコンソール画面からリソースがなくなっていることを確認します。

 

さいごに

今回はTerraformのSetUPを行ってから実行するまでの基本的な使い方の説明となりました。
ご紹介した基本的な機能はほんの一部です。他にも各種ツールとの連携や組み込み関数など様々な機能がありますが、それらはまた別な機会に紹介したいと思います。