LiBz Tech Blog

LiBの開発者ブログ

Terraform ことはじめ

あけましておめでとうございます

年末年始は実家でポケモンGO活に明け暮れていました。

コダックとコラッタばかりで地域格差をひしひしと感じました。

※ 去年末、社内勉強会でTerraform入門会を開催しました。一部内容変えて記事にしています。

いざ概論

弊社インフラを支えるTerraform の基礎を説明しながらお伝えする勉強会。

Terraform とは

お決まり f:id:kazunosuket:20190108101612p:plain

ではなく https://www.terraform.io/ より

Cloud Infrastructure Automation Consistent workflows to provision, secure, connect, and run any infrastructure for any application.

クラウドインフラストラクチャの自動化。

あらゆるアプリケーションのインフラストラクチャをプロビジョニング、セキュリティ、接続、実行するための一貫したワークフロー。

一言でいうと、インフラをコードで管理できるようにするツール(infrastructure as code)。

他にはどんな管理ツールがあるの?

よく比較される、有名所はこのあたり。

  • Ansible
  • AWS CloudFormation

Terraform との比較はこちらを参考にさせていただきました。 https://technodrone.blogspot.com/2018/06/comparing-cloudformation-terraform-and.html

EIGOでこんなことが書いてある。

・VPC を単独で立てるまでに必要な行数は?

Ansible - 19
CloudFormation - 28
Terraform - 29

・起動/削除にかかる時間は?(3回繰り返したときにかかる時間)

Ansible
create: 8.144s
destroy: 2.554s

CloudFormation
create: 31.987s
destroy: 31.879s

Terraform
create: 17.452s
destroy: 12.652s

・結論は?

Ansible 早くて記述量も少なくて良い(今回のケースでは)

・本音は?

Ansible が好きだけど、時々Terraform も良いなって思うし、たまにはCloudFormation もありだと思う。

-> そんな変わらないということらしい。

EC2を立ち上げてみよう

4StepでEC2が立ち上がる想定(すごい)

  1. Terraform ファイル書く
  2. 初期化する
  3. dry-run する
  4. 立ち上げる

1. Terraform ファイル書く

provider "aws" {
  access_key = "ACCESS_KEY"
  secret_key = "SECRET_KEY"
  region     = "us-east-1" # バージニア北部
}
 
resource "aws_instance" "broccoli" {
  ami           = "ami-2757f631"
  instance_type = "t2.micro"
}

雰囲気で読みましょう。

記述量少ないですがこれでEC2の設定が最低限完了します。

2. 初期化する

kazunosuke_t@kazlib:~/Dev/terraform $ terraform init

Initializing provider plugins...
- Checking for available provider plugins on https://releases.hashicorp.com...
- Downloading plugin for provider "aws" (1.50.0)...

The following providers do not have any version constraints in configuration,
so the latest version was installed.

To prevent automatic upgrades to new major versions that may contain breaking
changes, it is recommended to add version = "..." constraints to the
corresponding provider blocks in configuration, with the constraint strings
suggested below.

* provider.aws: version = "~> 1.50"

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.

3. 確認する(dry-run)

kazunosuke_t@kazlib:~/Dev/terraform $ terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.


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

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_instance.broccoli
      id:                           <computed>
      ami:                          "ami-2757f631"
      arn:                          <computed>
      associate_public_ip_address:  <computed>
      availability_zone:            <computed>
      cpu_core_count:               <computed>
      cpu_threads_per_core:         <computed>
      ebs_block_device.#:           <computed>
      ephemeral_block_device.#:     <computed>
      get_password_data:            "false"
      instance_state:               <computed>
      instance_type:                "t2.micro"
      ipv6_address_count:           <computed>
      ipv6_addresses.#:             <computed>
      key_name:                     <computed>
      network_interface.#:          <computed>
      network_interface_id:         <computed>
      password_data:                <computed>
      placement_group:              <computed>
      primary_network_interface_id: <computed>
      private_dns:                  <computed>
      private_ip:                   <computed>
      public_dns:                   <computed>
      public_ip:                    <computed>
      root_block_device.#:          <computed>
      security_groups.#:            <computed>
      source_dest_check:            "true"
      subnet_id:                    <computed>
      tenancy:                      <computed>
      volume_tags.%:                <computed>
      vpc_security_group_ids.#:     <computed>


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.

Terrraform ファイルで指定したamiinstance_typeが指定された値になっていることがわかる。

標準出力行頭の「+」は追加を表すシンボルのようなものです。

変更内容によって「-」や「~」などのシンボルもありますが今回は省きます。

4. 立ち上げる

kazunosuke_t@kazlib:~/Dev/terraform $ terraform apply

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_instance.broccoli
      id:                           <computed>
      ami:                          "ami-2757f631"
      arn:                          <computed>
      associate_public_ip_address:  <computed>
      availability_zone:            <computed>
      cpu_core_count:               <computed>
      cpu_threads_per_core:         <computed>
      ebs_block_device.#:           <computed>
      ephemeral_block_device.#:     <computed>
      get_password_data:            "false"
      instance_state:               <computed>
      instance_type:                "t2.micro"
      ipv6_address_count:           <computed>
      ipv6_addresses.#:             <computed>
      key_name:                     <computed>
      network_interface.#:          <computed>
      network_interface_id:         <computed>
      password_data:                <computed>
      placement_group:              <computed>
      primary_network_interface_id: <computed>
      private_dns:                  <computed>
      private_ip:                   <computed>
      public_dns:                   <computed>
      public_ip:                    <computed>
      root_block_device.#:          <computed>
      security_groups.#:            <computed>
      source_dest_check:            "true"
      subnet_id:                    <computed>
      tenancy:                      <computed>
      volume_tags.%:                <computed>
      vpc_security_group_ids.#:     <computed>


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 とタイプ。

  Enter a value: yes

aws_instance.broccoli: Creating...
  ami:                          "" => "ami-2757f631"
  arn:                          "" => "<computed>"
  associate_public_ip_address:  "" => "<computed>"
  availability_zone:            "" => "<computed>"
  cpu_core_count:               "" => "<computed>"
  cpu_threads_per_core:         "" => "<computed>"
  ebs_block_device.#:           "" => "<computed>"
  ephemeral_block_device.#:     "" => "<computed>"
  get_password_data:            "" => "false"
  instance_state:               "" => "<computed>"
  instance_type:                "" => "t2.micro"
  ipv6_address_count:           "" => "<computed>"
  ipv6_addresses.#:             "" => "<computed>"
  key_name:                     "" => "<computed>"
  network_interface.#:          "" => "<computed>"
  network_interface_id:         "" => "<computed>"
  password_data:                "" => "<computed>"
  placement_group:              "" => "<computed>"
  primary_network_interface_id: "" => "<computed>"
  private_dns:                  "" => "<computed>"
  private_ip:                   "" => "<computed>"
  public_dns:                   "" => "<computed>"
  public_ip:                    "" => "<computed>"
  root_block_device.#:          "" => "<computed>"
  security_groups.#:            "" => "<computed>"
  source_dest_check:            "" => "true"
  subnet_id:                    "" => "<computed>"
  tenancy:                      "" => "<computed>"
  volume_tags.%:                "" => "<computed>"
  vpc_security_group_ids.#:     "" => "<computed>"
aws_instance.broccoli: Still creating... (10s elapsed)
aws_instance.broccoli: Still creating... (20s elapsed)
aws_instance.broccoli: Still creating... (30s elapsed)
aws_instance.broccoli: Still creating... (40s elapsed)
aws_instance.broccoli: Creation complete after 42s (ID: i-0301c484d04a2bf26)

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

立ち上がった感ある。

コンソールを確認

f:id:kazunosuket:20190108101434p:plain

ブロッコリーが立ち上がった。

今日のまとめ

  • Terraform とは、インフラをコードで管理できるようにするツール
  • 少ない記述量で簡単にEC2立ち上れる
  • 試すだけならterraform init/plan/apply だけでなんとかなる