LoginSignup
14
10

More than 3 years have passed since last update.

Terraformハンズオン~基本編~

Last updated at Posted at 2019-10-29

はじめに

SREチームでTerraformを利用していくにあたって、周囲の理解が必要なことがありますよね。
この記事の背景として、社内に理解者を増やして、ツールの導入をスムーズにしたいという想いがあります。
ということで、社内のサーバーサイドエンジニアのようなインフラ系専門エンジニアではない人向けに社内Terraform共有会を開催する目的で書いています。

目次

Infrastructure as Codeとは何か

What
オライリー・ジャパンから出版されている『Infrastructure as Code』より引用するとIaCは以下のような定義となる。

Infrastructure as Codeは、ソフトウェア開発のプラクティスをインフラのオートメーションに活かすアプローチだ。1

Why
どうしてInfrastructure as Codeを行うかというと以下のような効果を期待するためだ。

● ITインフラが変化の障害や制約になるのではなく、変化を支えて実現すること。
● システム変更がユーザーやITスタッフのストレスや大事件ではなく、日常作業になること。
● ITスタッフが、日常的反復的なタスクではなく、彼らの能力を活かした価値のある仕事のために時間を使うこと
● ユーザーがITスタッフに頼るのではなく、自分で必要なリソースを定義、プロビジョニング、管理できるようになること。
● 失敗を完全に予防できるという前提に立つのではなく、失敗が発生しても簡単かつスピーディに回復できるようになること。
● コストがかかりリスキーな「ビッグバン」プロジェクトではなく、継続的な作業により改善、改良を実現すること。
● 会議やドキュメントでソリューションを論ずることではなく、実装、テスト、計測を通じてソリューションの効果が証明されるようになること。2

How
具体的にどのようなことをしていくかというと、ソフトウェア開発で行ってきたバージョン管理、自動テストライブラリ、デプロイのオーケストレーションといったことをインフラ管理にも応用していく。

Terraformの説明

Infrastructure as Codeツール分類

Terraformは『Infrastructure as Code』で紹介されるツール分類より引用すると以下の4つ3の中でインフラストラクチャ定義ツールに該当する。

  • ダイナミックインフラストラクチャプラットフォーム(AWS、GCP、Azure等)
  • インフラストラクチャ定義ツール(Terraform、CloudFormation等)
  • サーバー構成ツール(Ansible、Chef、Puppet等)
  • インフラストラクチャサービス(Datadog、NewRelic、CircleCI等)

Terraformとは

image.png

  • HashiCorpが作成したオープンソースの構成管理ツール。
  • 例えばクラウドベンダー(AWS、GCP、Azure)のクラウドリソースのインフラ構成を宣言的に定義できるところが特徴。構成手順を書くのではなく、構成定義を書くという形になる。(Ansibleとの違い)
  • Providersには、物理マシン、VM、ネットワークスイッチ、コンテナ、監視ツール、データベース等の色々な選択肢がある。
  • ファイルはHashiCorp Configuration Language (HCL) で記述される。

Terraformの仕組み

Terraformはtfstateと呼ばれるファイルとHCLの差分を確認して、必要な部分だけに変更をかけてくれる。
tfstateファイルはTerraformを一度でもapplyすれば作成され、現在の状態を記録してくれる。

図はTakahisa Iwamoto氏の資料を見るとイメージが付きやすいのでおすすめ。

Terraformのメリット

  • HCLで宣言的にリソース定義ができ、リソース作成順序を自動的に判断してくれるため、リソース変更作業者のケアレスミスを回避できる。
  • クラウドベンダーを選ばずTerraformでソースコード管理することができる。
  • 繰り返し行われるインフラ構築作業トイルを巻き取ってくれる可能性がある。

Terraformのデメリット

  • HCLの記法や各構築対象サービスのお作法を学ぶ必要がある。
  • ツール自体開発が活発に行われている最中であるため、新しい記法やお作法の情報を追従することが必要になる。
  • 破壊的変更を伴う作業ができてしまうので対策が必要になる。

Terraformを安全に使うためには

Terraformではライフサイクルによる削除抑止定義を行うことができる

lifecycle{
  prevent_destroy=true
}

このように削除されたくないリソースに関しては設定を入れると削除できなくなります。
ただし、この設定を入れても絶対安全というわけではなく、リソース定義自体を消してapplyすれば削除されてしまう。
apply時は実行者によるチェックも重要になってくる。

Terraformハンズオン

AWSのセットアップ

AWSのIAMユーザーを作成

  • AWSマネジメントコンソールのIAMに移動
  • ユーザー → ユーザーを追加の順にクリック
  • ユーザー名を入力
  • プログラムによるアクセス → 次のステップ:アクセス権限
    image.png

  • 既存のポリシーを直接アタッチ → AdministratorAccessをチェック → 次のステップ:タグ
    image.png

  • タグは追加せず → 次のステップ:確認

  • ユーザーの作成

AWS CLI

AWS CLIをpip3からインストールします。インストールしたらバージョンを確認してみます。

$ pip3 install awscli --upgrade

# 確認
$ aws --version

クレデンシャルを環境変数として設定

AWSマネジメントコンソールからアクセスキーID、シークレットアクセスキーをコピーしてexportする。

$ export AWS_ACCESS_KEY_ID=XXXXXXXXXXXXXXXXXXXX
$ export AWS_SECRET_ACCESS_KEY=XXXXXXXXXX/XXXXXXXXXX/XXXXXXXXXX
$ export AWS_DEFAULT_REGION=ap-northeast-1

Terraformのセットアップ

そしていよいよTerraformのインストールを行うが、今後のバージョン管理も考えてtfenvでのインストールをここでは記載しておく。

tfenvのインストール

tfenvはTerraformのバージョンマネージャー。バージョンを上げたり下げたりしたい場面で非常に有効になるのでこちらでのインストールをお勧めする。

# Macの場合
$ brew install tfenv
# 確認
$ tfenv --version
tfenv 1.0.1

# それ以外の場合
$ git clone https://github.com/tfutils/tfenv.git ~/.tfenv
$ echo 'export PATH="$HOME/.tfenv/bin:$PATH"' >> ~/.bash_profile
$ source ~/.bash_profile
# 確認
$ tfenv --version
tfenv 1.0.1

READMEではシンボリックリンクによるPATH設定の方法もあるので好みで選択できる。

tfenvの使い方

tfenv list-remote

インストールできるバージョンの一覧を取得する。

$ tfenv list-remote
0.12.12
0.12.11
0.12.10
0.12.9
...

tfenv install

対象のバージョンをインストールする。

$ tfenv install 0.12.12

tfenv list

インストール済みのバージョンを確認する。

$ tfenv list
* 0.12.12 (set by /usr/local/Cellar/tfenv/1.0.1/version)
  0.12.5

tfenv use

複数バージョンを切り替える場合はuseを使う。

$ tfenv use 0.12.5

AWS EC2を作成してみる

作業ディレクトリの作成

Terraform作業用にディレクトリを用意する。

$ mkdir terraform_test
$ cd terraform_test
$ vim main.tf

main.tfには以下を記載する。

resource "aws_instance" "test" {
  ami           = "ami-04b9e92b5572fa0d1"
  instance_type = "t3.micro"
}

terraform init

コードを記載したら、main.tfがあるディレクトリでterraform initを実行して、バイナリファイルをダウンロードする。

$ terraform init
Initializing the backend...
Terraform has been successfully initialized!

$ terraform plan
terraform planで実行計画を出力させて、どのような変更が行われるか確認する。

$ 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_instance.test will be created
  + resource "aws_instance" "test" {
      + ami                          = "ami-04b9e92b5572fa0d1"
      + arn                          = (known after apply)
      + associate_public_ip_address  = (known after apply)
      + availability_zone            = (known after apply)
      + cpu_core_count               = (known after apply)
      + cpu_threads_per_core         = (known after apply)
      + get_password_data            = false
      + host_id                      = (known after apply)
      + id                           = (known after apply)
      + instance_state               = (known after apply)
      + instance_type                = "t3.micro"
   ......}

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

+マークがでているところが重要で、新規にリソースを作成するという意味になる。

terraform apply

terraform applyで実行計画からでていた変更を実際に行わせる。

$ terraform apply
......
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を入力すると実行される。

aws_instance.test: Creating...
aws_instance.test: Still creating... [10s elapsed]
aws_instance.test: Creation complete after 18s [id=i-095131324a66cb153]

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

AWSマネジメントコンソールでEC2インスタンスができていることを確認する。

AWS EC2の情報を更新してみる

EC2の作成に成功したら、変更をしてみる。
先程作成したmain.tfを以下に書き換える。

resource "aws_instance" "test" {
  ami           = "ami-04b9e92b5572fa0d1"
  instance_type = "t3.micro"

  tags = {
    Name = "test"
  }
}

コードを修正したらterraform applyを実行する。

+マークから~マークに変化してaws_instance.test will be updated in-placeが表示される。
これは既存のリソースの設定を変更するという意味になる。

AWSマネジメントコンソールでも、Nameタグの追加が確認できる。

AWS EC2を再作成してみる

Nginxをインストールするため、以下のようにmain.tfを変更してapplyする。

resource "aws_instance" "test" {
  ami           = "ami-04b9e92b5572fa0d1"
  instance_type = "t3.micro"

  user_data = <<EOF
    #!/bin/bash
    apt-get install nginx
    systemctl start nginx.service
EOF
}

今度は-/+マークがつきaws_instance.test must be replacedというメッセージが表示される。
これは既存のリソースを削除して新しいリソースを作成するという意味になる。

リソースの削除を伴う作業になるので、本当に実行していいのか確認する必要がある。

AWS EC2を削除する

terraform destroyで作成したリソースを削除できる。

-マークがつきaws_instance.test will be destroyedというメッセージが表示される。
これは既存のリソースを削除するという意味になる。

参考

今回は触りしか書かなかったので、もしより詳しくTerraformを知りたい場合はこちらを購入することをオススメする。
野村 友規. 実践Terraform AWSにおけるシステム設計とベストプラクティス


  1. Kief Morris(2017年03月)『Infrastructure as Code』(宮下 剛輔 監訳、長尾 高弘 訳) オライリー・ジャパン 「1章課題と原則 1.2 Infrastructure as Codeとは何か」 より引用 

  2. Kief Morris(2017年03月)『Infrastructure as Code』(宮下 剛輔 監訳、長尾 高弘 訳) オライリー・ジャパン 「1章課題と原則 1.2.1 Infrastructure as Codeの目標」 より引用 

  3. Kief Morris(2017年03月)『Infrastructure as Code』(宮下 剛輔 監訳、長尾 高弘 訳) オライリー・ジャパン 「1章課題と原則 1.8 この後の章について」 より引用 

14
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
10