【初学者向け入門編】 terraformとは ? 概要+実践で解説します

ITインフラ

【初学者向け入門編】 terraformとは ? 概要+実践で解説します

terraformとは IaCを実現するためのツールです。

今回は初学者向けに概要からインストール、初回実行までを解説します。

一緒に手を動かして terraform を使ってIaCしていきましょう!

こんな人に見て欲しい!

  • IaCは何となくわかったが、具体的にどうすれば良いのかわからない方
  • terraformを使ってみたいけど、使い方がいまいちイメージできていない方
  • IaCもterraformもよくわからんがやってみたいという方

実際に使ったりしないけど、知識として知っておきたいという方もぜひ最後までご覧ください。

※後半で、実際にインストールから実行までのコマンドなどを掲載していますがmacOSのものになります。

terraformとは

terraformは、Hashicorp社の提供するIaCを行うためのツールです。

terraformを使うと、HashicorpConfigurationLanguage(HCL)という言語で書かれた定義ファイルをもとに、AWS、GCPなどのさまざまなプロバイダーに対してIaCを行うことができます。

terraformを使うメリット

様々なサイトでも取り上げられていますが、私自身使っていて感じるメリットを挙げさせていただきます。

学習コストが低い

terraformでは、HashicorpConfigurationLanguage(HCL)というプログラミング言語的なものを使います。

プログラミング言語と聞くと身構えてしまいますが、そんなに難しいものではありません。

先にちょっと覗いてみると、、、


resource "aws_vpc" "vpc" {
  cidr_block       = "10.0.0.0/16"
  instance_tenancy = "default"

  tags = {
    "Name" = "hitolog-vpc"
  }
}

cidr_blockやinstance_tenancyなどの設定項目に値を指定してあげる感じです。

設定項目も、公式ドキュメントに記載されているので進めやすいです。

多少ロジカルな記述ができる

terraformでは、繰り返しは、三項演算子など多少ロジカルな記述が可能です。

例えば、EC2インスタンスを100個作らなければいけない場合、terraformの場合は設定項目にcount=100と書くだけで100個作れます。

しかし、繰り返しが使えないCloudFormationの場合EC2インスタンスを作成する記述を100個書く必要があり、コードが非常に長くなってしまいます。

このように、低い学習コストでそこそこ便利な機能があるというところもterraformを使うメリットになります。

CloudFormationとは

AWSが提供するサービスの一つで、YAML形式のコードからAWS常にリソースを作成してくれます。

定義ファイルがYAMLなのでさらにシンプルで、公式ドキュメントも充実しているため学習コストはterraformよりも低い印象です。

マルチプロバイダーに対応

冒頭にも記載しましたが、terraformはサードパーティ製のツールであるためAWSに限らずGCPやAzureなどでも利用することができます。

対応プロバイダー一覧

定義ファイルの書き方が多少異なりますが、基本はどれもHCLで記述しますので一つのプロバイダーで学習したHCLが他のプロバイダーでも応用できるといった利点があります。

terraformを使うために必要なもの

terraformを使うために必要なものを先にまとめておきます。(PCなどはある前提です)

terraformを使うために必要なもの

  • tfenv
  • terraform本体
  • HashicorpConfigurationLanguage(HCL)で書かれた定義ファイル
  • リソースを作成する先の認証情報(今回はAWS)

今回ご紹介する方法では、プロバイダーはAWSとしています。

AWSにリソースを作る場合は、terraformの他にAWS CLIのセットアップとアクセスキーの設定が必要です。
こちらの記事でアカウント作成後から、CLIの設定までの手順を解説していますので参考に準備してください!

tfenvのインストール方法

tfenvは、terraformのバージョンを切り替えたりするためのツールになります。

詳細は省きますがこんなイメージです。

terraformとは tfenv

macをご利用であればbrew install コマンドで簡単にインストールできます。

$ brew install tfenv
$ tfenv --version
tfenv 2.2.3

terraformのインストール方法

次に、先ほどインストールしたtfenvを使ってterraformをインストールしていきます。

$ tfenv list-remote
# インストール可能なバージョンがずらっと出てきます。
1.1.5
1.1.4
1.1.3
1.1.2
1.1.1
1.1.0
・・・省略・・・


$ tfenv use 1.1.5
$ tfenv list
$ terraform -v
Terraform v1.0.6
on darwin_amd64
+ provider registry.terraform.io/hashicorp/aws v3.58.0

Your version of Terraform is out of date! The latest version
is 1.0.7. You can update by downloading from https://www.terraform.io/downloads.html

この中から、tfenv install コマンドでバージョン1.1.5のterraformをインストールしていきます。

$ tfenv install 1.1.5
Installing Terraform v1.1.5
Downloading release tarball from https://releases.hashicorp.com/terraform/1.1.5/terraform_1.1.5_darwin_amd64.zip
#=#=-  #       #                                                                                                                                                                                                                                               #=O=#     #    ######################################################################################################################################################################################################################################################### 100.0%
Downloading SHA hash file from https://releases.hashicorp.com/terraform/1.1.5/terraform_1.1.5_SHA256SUMS
No keybase install found, skipping OpenPGP signature verification
Archive:  /var/folders/cb/z_wlr8x14vsb4gx041j_v8dc0000gn/T/tfenv_download.XXXXXX.4GPhg19i/terraform_1.1.5_darwin_amd64.zip
  inflating: /usr/local/Cellar/tfenv/2.2.3/versions/1.1.5/terraform
Installation of terraform v1.1.5 successful. To make this your default version, run 'tfenv use 1.1.5'

プログレスバーが100%まで進み、最後に「 Installation of terraform v1.1.5 successful. ~~~ 」と出ていればOKです。

ここまででtfenvにはインストールされているのですが、どのバージョンを使うか明示的に指示していないので使うことができません。

インストール後は、tfenv use コマンドで使用するterraformのバージョンを指定しましょう。

# tfenvにインストールされているバージョンを表示するコマンド
$ tfenv list
  1.1.5
# どのバージョンも指定されていないので警告がでる。
No default set. Set with 'tfenv use <version>'

# 先程インストールした1.1.5を使用する
$ tfenv use 1.1.5
Switching default version to v1.1.5
Switching completed

# terraformのバージョンを確認する
$ terraform version
Terraform v1.1.5

バージョンを指定しなかった場合のエラー

ちなみに、バージョンを指定しなかった場合は以下のようなエラーになります。

# tfenv use <version>を実行する前にterraformのバージョンを確認しようとすると

$ terraform  version
cat: /usr/local/Cellar/tfenv/2.2.3/version: No such file or directory
Version could not be resolved (set by /usr/local/Cellar/tfenv/2.2.3/version or tfenv use <version>)

定義ファイルの書き方

terraformのインストールが完了したら、次はインフラを定義するためのファイルを作成します。

なるべくシンプルにご紹介するために、VPCという仮想ネットワークの作成のみを行うファイルを作成します。

それがこちら。(コピペで使えます)

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 3.27"
    }
  }
}


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

# --------------------------------------------#
# VPC
# --------------------------------------------#

resource "aws_vpc" "vpc" {
  cidr_block       = "10.0.0.0/16"
  instance_tenancy = "default"
  tags = {
    "Name" = "hitolog-vpc"
  }
}

{}で囲まれた一つのまとまりが1ブロックとなっており、その前にterraformと名前がついていれば、それはterraformブロックとなります。

この例では、以下の3つのブロックに分かれていることがわかります。

  • terraformブロック
  • providerブロック
  • resourceブロック

それぞれの役割をご紹介します。

terraformブロック

このブロックは、terraformを定義するブロックになります。

required_providersで今回対象にするプロバイダーを指定し、必要な情報をsourceから取得するための定義です。

ある程度定型文なので、公式ドキュメントからコピーするのがいいかと思います。

providerブロック

ここではterraformブロックで取得したawsというプロバイダーの設定を定義しています。

今回は、profile = "default"となっているのでAWS CLIで設定したdefaultのプロファイルがAWSとの接続に使われます。

resourceブロック

ここでは実際に作成するリソースを定義しており、例ではVPCを作成したかったのでaws_vpcという語句が頭についています。

サブネットやセキュリティーグループなど別のリソースを作成したい場合はterraformの公式ドキュメントからaws_vpcに相当するものを検索して記述してあげる必要があります。

terraformとは 公式ドキュメントからresoueceブロックの書き方を検索する方法

画像のように、検索するとresourceブロックの名称や必要なパラメータが出てきますのでとりあえずコピペで試してみましょう。

公式のドキュメント読むのがきつい方へ

私も最初苦痛でした。。。そんなときは必ずしも公式ドキュメントを参照する必要はありません。

企業や個人のブログで掲載されているサンプルやREADMEの充実したgithubのコードを参考に、「とりあえず動かす」というところに重点を置いてやってみましょう。

参考までに、定義ファイルのサンプルと実行結果などが載っているようなサイトが良いかと思います。

terraformを実行する

ファイルの用意ができたらいよいよ実行です。

この記事では以下のような構成で準備しました。

$ pwd
~/hitolog_sample
$ ls
main.tf

定義ファイルの準備ができたら最初に実行するべきコマンドがあります。

$ terraform init
Initializing the backend...

Initializing provider plugins...
- Finding hashicorp/aws versions matching "~> 3.27"...
- Installing hashicorp/aws v3.74.2...
- Installed hashicorp/aws v3.74.2 (signed by HashiCorp)

Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

ここで何をしているのかというと、定義ファイルで指定したプロバイダーに対して操作するのに必要なものをhashicorp/awsというところから取得してきています。

つぎに、terraform planコマンドで実行結果を見てみましょう。

$ terraform plan
Terraform used the selected providers to generate the following execution plan. 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)
      + cidr_block                           = "10.0.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)
      + ipv6_cidr_block_network_border_group = (known after apply)
      + main_route_table_id                  = (known after apply)
      + owner_id                             = (known after apply)
      + tags                                 = {
          + "Name" = "hitolog-vpc"
        }
      + tags_all                             = {
          + "Name" = "hitolog-vpc"
        }
    }

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

──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run
"terraform apply" now.

terraform planコマンドでは実際にリソースの作成は行われません。

定義ファイルを実行した場合に作成/削除/変更されるリソースを実行前に確認することができます。

既存のシステムに際して変更を行う際、削除/変更対象が間違っていないかここで確認することができます。

最後に実行します。

$ terraform apply

Terraform used the selected providers to generate the following execution plan. 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)
      + cidr_block                           = "10.0.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)
      + ipv6_cidr_block_network_border_group = (known after apply)
      + main_route_table_id                  = (known after apply)
      + owner_id                             = (known after apply)
      + tags                                 = {
          + "Name" = "hitolog-vpc"
        }
      + tags_all                             = {
          + "Name" = "hitolog-vpc"
        }
    }

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

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes <=========ここでyesと入力


aws_vpc.vpc: Creating...
aws_vpc.vpc: Creation complete after 2s [id=vpc-0126d0d05c9e5809b]

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

最初はterraform planコマンドと同じように実行結果が出力されます。

実行して良いか聞かれるので、問題なければ「yes」と入力して実行します。

以降、terraformによって粛々とリソースが作成されますので待つだけです。

完了後、vpcの一覧を確認すると

$ aws ec2 describe-vcps
{
    "Vpcs": [
        {
            "CidrBlock": "10.0.0.0/16",
            "DhcpOptionsId": "dopt-053c0fa1f2f5deb1b",
            "State": "available",
            "VpcId": "vpc-0126d0d05c9e5809b",
            "OwnerId": "296066267476",
            "InstanceTenancy": "default",
            "CidrBlockAssociationSet": [
                {
                    "AssociationId": "vpc-cidr-assoc-021a6bed4cb7a97a5",
                    "CidrBlock": "10.0.0.0/16",
                    "CidrBlockState": {
                        "State": "associated"
                    }
                }
            ],
            "IsDefault": false,
            "Tags": [
                {
                    "Key": "Name",
                    "Value": "hitolog-vpc"
                }
            ]
        }
    ]
}

確認できたら、このまま公式ドキュメントなどを参考にサブネットの作成など進めても良いですがリソース削除のやり方も確認しておきましょう。

削除も簡単で、terraform destroyコマンドを実行することで定義ファイルに記載されているリソースを全て削除することができます。

$ terraform destroy
aws_vpc.vpc: Refreshing state... [id=vpc-0126d0d05c9e5809b]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following
symbols:
  - destroy

Terraform will perform the following actions:

  # aws_vpc.vpc will be destroyed
  - resource "aws_vpc" "vpc" {
      - arn                              = "arn:aws:ec2:ap-northeast-1:296066267476:vpc/vpc-0126d0d05c9e5809b" -> null
      - assign_generated_ipv6_cidr_block = false -> null
      - cidr_block                       = "10.0.0.0/16" -> null
      - default_network_acl_id           = "acl-011db904ec6cfe5ee" -> null
      - default_route_table_id           = "rtb-084543d6c5b677da8" -> null
      - default_security_group_id        = "sg-041e10fa81da08844" -> null
      - dhcp_options_id                  = "dopt-053c0fa1f2f5deb1b" -> null
      - enable_classiclink               = false -> null
      - enable_classiclink_dns_support   = false -> null
      - enable_dns_hostnames             = false -> null
      - enable_dns_support               = true -> null
      - id                               = "vpc-0126d0d05c9e5809b" -> null
      - instance_tenancy                 = "default" -> null
      - ipv6_netmask_length              = 0 -> null
      - main_route_table_id              = "rtb-084543d6c5b677da8" -> null
      - owner_id                         = "296066267476" -> null
      - tags                             = {
          - "Name" = "hitolog-vpc"
        } -> null
      - tags_all                         = {
          - "Name" = "hitolog-vpc"
        } -> null
    }

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

Do you really want to destroy all resources?
  Terraform will destroy all your managed infrastructure, as shown above.
  There is no undo. Only 'yes' will be accepted to confirm.

  Enter a value: yes <=======ここでも確認が入ります。

aws_vpc.vpc: Destroying... [id=vpc-0126d0d05c9e5809b]
aws_vpc.vpc: Destruction complete after 1s

Destroy complete! Resources: 1 destroyed.

terraform.tfstateってなに?

terraform applyを実行した後、ディレクトリ内を確認すると作成した覚えのないファイルが2つできているかと思います。

これらは、terraform applyコマンドの実行後に作成・更新されるファイルで、非常に重要なファイルになっています。

$ ls
main.tf                  terraform.tfstate        terraform.tfstate.backup

terraform.tfstateの中身を見てみると先ほどterraformで作成したリソースが記載されています。

実際のリソースと、terraformで管理している情報を紐づけているのがterraform.tfstateというファイルの役割です。

複数人で同じリソースを管理する場合などは、これをS3やgithubなどで管理すると良いでしょう。

$ pwd
~/hitolog_sample
$ ls
main.tf                  terraform.tfstate        terraform.tfstate.backup

実行後に生成されるterraform.tfstateについて

terraform applyコマンドを実行した後同じディレクトリ内を確認すると、terraform.tfstateとterraform.tfstate.backupが生成されています。

terraform.tfstateの中身を見てみると先ほどterraformで作成したリソースが記載されています。

実際のリソースと、terraformで管理している情報を紐づけているのがterraform.tfstateというファイルの役割になります。

このファイルが削除されてしまうと、terraformはどのリソースを管理しているのかわからなくなってしまいます。

terraformとは tfstateについて

複数人でterraformを使い同じリソースを管理する場合、このterraform.stateというファイルをS3やgithubなどのリモートリポジトリにおいてくことで、それぞれ同じterraform.tfstateを参照させることができます。

別々のPCからでも同じリソースを管理することができます。

まとめ

今回の総括です。

まず概要的なところから総括します。

terraformとは

  • IaCを実現するためのサードパーティ製ツール
  • 学習コストが低い割に、便利で、さまざまなプロバイダー応用が効く
  • 必要なものは、tfenvterraform定義ファイル

続きまして、実行までの流れをまとめます。

terraform実行までの流れ

  • 定義ファイルの準備(XXXX.tf)
  • terraform initの実行
  • terraform planで結果だけ確認
  • terraform applyでリソース作成
  • terraform.tfstateは大事にとっておく!

参考

ITインフラ

Posted by kotaro