はじめに
こんにちは!!
CYBIRD Advent Calendar 2022 8日目担当のもっふんにゃです。
7日目は@tomoko_ishizakaさんの「ストーリー仕立てで理解する、AWSのIAM周りとアカウントの超入門知識」でした。
是非こちらも合わせてご覧ください!
私は今年の4月にエンジニアとして新卒入社しました。
これまで研修経て、現在ではインフラチームでOJTを受けているのですが、その中で革命的な概念・ツールに出会ってしまいました。
それが「Infrastructure as Code」という概念とそれを体現する「Terraform」というツールです。
今回は、私が衝撃を受けたこの「Terraform」について、インストールからインフラの構築・変更・破壊・変数定義・出力値設定まで伝えたいと思います!
Terraformとは
Terraformは、HashiCorpが提供するInfrastructure as Code (IaC) ツールです。
IaCツールを使うと、コンソールなどのグラフィカルなユーザーインターフェイスではなく、設定ファイルを使ってインフラ構築、変更、管理を行うことができます。
ずっとコンソールでポチポチやっていた身としては、設定ファイル(ソースコード)を使ってポチっとするだけで簡単にインフラを構築できる革命的に便利なツールです。出会った時には感動しました。
あらゆるインフラを管理
Terraformは、AWS, Azure, GCP, Kubernetes, Helm, GitHub, Splunk, DataDogなど、1,000以上のプロバイダで、リソースを管理することができます。
その中で今回はAWSでのインフラ構築を行なっていきます!!
Terraformのインストール
Terraformを使うには、インストールが必要です。
Terraformをインストールするには、こちらからシステムに適したパッケージを見つけ、ZIPファイルをダウンロードするか、あるいはコマンドラインでバイナリを取得する方法があります。
今回はMacで進めているのでHomebrewを使ってコマンドライン(ターミナル)からインストールしていきます。
HomebrewはフリーでオープンソースのMacOSX用パッケージ管理システムです。
※Homebrewのインストールについてはこちらからお願いいたします。
まず、HashiCorp tapをインストールします。
$ brew tap hashicorp/tap
次に、hashicorp/tap/terraform
でTerraformをインストールします。
$ brew install hashicorp/tap/terraform
Terraform の最新版に更新するには、Homebrewを更新します。
$ brew update
upgrade
コマンドを実行して、最新のTerraformのバージョンをダウンロードします。
$ brew upgrade hashicorp/tap/terraform
インストールを確認
新しいターミナルウィンドウを開いて、インストールがうまくいったことを確認します。
$ terraform -version
Terraform v1.3.5
on darwin_amd64
上記の様にバージョンが表示されれば問題なくインストールされています!
terraform -help
コマンドを使ってTerraformで利用可能なサブコマンドをリストアップすることができます。
$ terraform -help
Usage: terraform [global options] <subcommand> [args]
The available commands for execution are listed below.
The primary workflow commands are given first, followed by
less common or more advanced commands.
Main commands:
init Prepare your working directory for other commands
validate Check whether the configuration is valid
plan Show changes required by the current configuration
apply Create or update infrastructure
destroy Destroy previously-created infrastructure
##...省略
インフラを構築
Terraformのインストールが完了したところで、いよいよ構築です!
今回はAWS(Amazon Web Services)のEC2インスタンスを起動してインフラを構築していきます。
※EC2インスタンス:AWS上で動作する仮想マシン
※無料枠の範囲内で構築していきます。
TerraformからAWS上にインフラを構築するには、以下の2点が必要です。
・AWS CLIのインストール
・AWSアカウントのアクセスキー
AWS CLIのインストール
まずはAWS CLIのインストールです。
今回はMacOSのターミナルからインストールしていきます。
curlコマンドを使用してファイルをダウンロードします。
$ curl "https://awscli.amazonaws.com/AWSCLIV2.pkg" -o "AWSCLIV2.pkg"
ダウンロードしたファイルを指定して、MacOSのinstallerプログラムを実行します。
$ sudo installer -pkg AWSCLIV2.pkg -target /
インストールが完了しましたので、確認を行います。
$ which aws
/usr/local/bin/aws
$ aws --version
aws-cli/2.7.24 Python/3.8.8 Darwin/18.7.0 botocore/2.4.5
上記の様で出ればAWS CLIが問題なくインストールされています。
アクセスキーを環境変数に設定
次にAWS CLIで使用するアクセスキーです。
TerraformからAWSへ認証する際に、IAMユーザーのアクセスキーが必要になります。
今回はAWSコンソール上で「terraform-test」というIAMユーザーを作成したので、このユーザーを使ってTerraformからインフラを構築します。
作成したIAMユーザーのアクセスキー、シークレットアクセスキーを環境変数に指定していきます。
$ export AWS_ACCESS_KEY_ID= <アクセスキー入力>
$ export AWS_SECRET_ACCESS_KEY= <シークレットアクセスキー入力>
コンフィギュレーションを書く
Terraformでインフラを記述するためのファイル群を「Terraformコンフィギュレーション」と言います。
Terraformのファイル群は独自のディレクトリに置かれている必要があるので、ディレクトリを作成します。
$ mkdir learn-terraform-aws-instance
ディレクトリに変更します。
$ cd learn-terraform-aws-instance
インフラを定義するファイルを作成します。
$ touch main.tf
テキストエディタでmain.tfを開き、以下のコンフィギュレーションを貼り付けて、ファイルを保存します。
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.16"
}
}
required_version = ">= 1.2.0"
}
provider "aws" {
region = "us-west-2"
}
#----------------------------------------
# EC2インスタンスの作成
#----------------------------------------
resource "aws_instance" "app_server" {
ami = "ami-830c94e3"
instance_type = "t2.micro"
tags = {
Name = "ExampleAppServerInstance"
}
}
ディレクトリの初期化
作成したコンフィギュレーションを使って、EC2インスタンスを構築していきます。
Terraformの実行に必要なプラグインをインターネットから取得しディレクトリを初期化します。
$ terraform init
実行結果に以下が表示されていれば成功です。
Terraform has been successfully initialized!
設定のフォーマットとバリデーション
terraform fmtコマンドを実行すると、コードのインデントを自動で整形することができます。
$ terraform fmt
また、terraform validateコマンドを実行すると、問題があった場合、ファイル名と行数を表示してくれます。
問題がない場合は以下の様に表示されます。
$ terraform validate
Success! The configuration is valid.
インフラストラクチャの作成
terraform applyコマンドで設定を適用します。
※TerraformがEC2インスタンスを利用できるようになるのを待つため、実行には数分かかります。
$ 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_instance.app_server will be created
+ resource "aws_instance" "app_server" {
+ ami = "ami-830c94e3"
+ arn = (known after apply)
##....省略
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:
構築内容に問題がなければ、Enter a value:
にYesと入力します。
Enter a value: yes
aws_instance.app_server: Creating...
aws_instance.app_server: Still creating... [10s elapsed]
aws_instance.app_server: Still creating... [20s elapsed]
aws_instance.app_server: Still creating... [30s elapsed]
aws_instance.app_server: Still creating... [40s elapsed]
aws_instance.app_server: Still creating... [50s elapsed]
aws_instance.app_server: Creation complete after 54s [id=i-*****************]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
これでTerraformを使ってインフラが構築されました!!
AWSコンソールで確認してみるとしっかり構築されていました!
状態の確認
terraform show
を使って現在のインフラの状態を確認できます。
$ terraform show
# aws_instance.app_server:
resource "aws_instance" "app_server" {
ami = "ami-830c94e3"
arn = "arn:aws:ec2:us-west-2:************:instance/i-*****************"
associate_public_ip_address = true
availability_zone = "us-west-2c"
cpu_core_count = 1
cpu_threads_per_core = 1
disable_api_stop = false
disable_api_termination = false
ebs_optimized = false
get_password_data = false
hibernation = false
id = "i-*****************"
instance_initiated_shutdown_behavior = "stop"
instance_state = "running"
instance_type = "t2.micro"
ipv6_address_count = 0
##....省略
インフラを変更
構築したリソースに対して変更を適用していきます。
ここではインスタンスのAMIを変更します。
詳細には、AWSでインスタンスを起動した後にAMIの変更はできないので、先ほど起動したインスタンスを破棄して新しくインスタンスを起動します!(これらはTerraformが自動でやってくれます!)
main.tfのresourceブロックにある、現在のAMI IDを別のものに置き換えます。
resource "aws_instance" "app_server" {
- ami = "ami-830c94e3" #削除
+ ami = "ami-08d70e59c07c61a3a" #追加
instance_type = "t2.micro"
}
この変更で、AMIがUbuntu 12.04からUbuntu 16.04に変更されます。
変更の適用
設定を変更したら、もう一度terraform applyを実行して、変更内容を確認します。
$ terraform apply
問題がなければEnter a value:
でyesと回答します。
Enter a value: yes
実行計画で示されているように、Terraformは先ほど作成した既存のインスタンスを破棄し、新しいインスタンスを起動しました。
これで変更が適応されています。
インフラを破壊
インフラが不要になったら、セキュリティ面でのリスクカットやコストを削減するために破棄したいことがあります。
Terraformは、インフラの構築と変更に加えて、管理するインフラを破壊したり再作成したりすることができます。
破棄する
terraform destroy
コマンドは、Terraformが管理するリソースを終了させます。
今回作成したTerraformプロジェクトの管理の外にあるリソースについては破壊しませんのでご安心ください。
作成したリソースを破棄します。
$ terraform destroy
問題がなければEnter a value:
でyesと回答します。
Enter a value: yes
これで今回作成されたリソースは破壊されました!
※複数のリソースがあるような場合は、Terraformが依存関係を考慮して適切な順序で破棄します。
入力変数の定義
ここまでのコンフィギュレーションではハードコードされた値を使っていました。
Terraformの設定には変数を含めることができ、より柔軟なものにすることができます。
インスタンス名を変数で設定
インスタンス名を定義するための変数を追加します。
learn-terraform-aws-instance
ディレクトリ内でvariables.tf
というファイルを新しく作成します。
$ touch variables.tf
新しい変数instance_name
を定義するブロックを作成します。
variables.tf
を開き、以下のコンフィギュレーションを貼り付けて、ファイルを保存します。
variable "instance_name" {
description = "Value of the Name tag for the EC2 instance"
type = string
default = "Tamagotoji"
}
上記の内容はinstance_name
について、別の値を宣言しない限り、デフォルトでTamagotoji
になります。
main.tf
を開き、新しい変数を使用するよう以下の変更点を修正し、ファイルを保存します。
resource "aws_instance" "app_server" {
ami = "ami-08d70e59c07c61a3a"
instance_type = "t2.micro"
tags = {
- Name = "ExampleAppServerInstance" #削除
+ Name = var.instance_name #追加
}
}
コンフィギュレーションを適用
コンフィギュレーションを適用します。
$ terraform apply
問題がなければEnter a value:
でyesと回答します。
Enter a value: yes
-var
オプションを使って変数を渡し、デフォルトのインスタンス名に上書きするため、もう一回設定を適用します。
$ terraform apply -var "instance_name=Moffunnya"
問題がなければEnter a value:
でyesと回答します。
Enter a value: yes
これでvariables.tf
内の変数から値を入力できる様になりました!
※コマンドラインから変数を設定しても、variables.tf
やmain.tf
などのコンフィギュレーションには保存されません。
コマンドラインに欲しい情報を出力
構築されたインフラ環境の欲しい情報について、コマンドラインで出力するように設定することができます。
出力用EC2インスタンスの設定
learn-terraform-aws-instance
ディレクトリにoutputs.tf
というファイルを作成します。
$ touch output.tf
以下の設定をoutputs.tf
に貼り付け、EC2インスタンスのID、IPアドレスの出力を定義します。
output "instance_id" {
description = "ID of the EC2 instance"
value = aws_instance.app_server.id
}
output "instance_public_ip" {
description = "Public IP address of the EC2 instance"
value = aws_instance.app_server.public_ip
}
出力値の適応、確認
terraform apply
で設定を適用します。
$ terraform apply
問題がなければEnter a value:
でyesと回答します。
Enter a value: yes
Terraformは設定を適用すると、出力値を画面に表示します。
出力するように設定した値はterraform output
コマンドで問い合わせることができます。
$ terraform output
instance_id = "i-*****************"
instance_public_ip = "**.**.**.**"
これでoutput.tf
で設定した出力値をコマンドラインで確認することができます!
終わりに
おつかれさまでした!!いかがでしたでしょうか?!!
今回は、「Terraform」について、インストール、インフラの構築・変更・破壊・変数定義・出力値設定まで伝えさせていただきました。
これまでコンソールでインフラを構築されてきた方は、私と同じ感動をえられたのではないでしょうか!!!
同じような環境構築を行う場面は多くあると思うので、Terraformの決まった構成の設定ファイルをいくつか持っておくと、思いもよらないところで活かせるかもしれません!!是非いろいろな構成で試してみてください!!
CYBIRD Advent Calendar 2022 9日目は@ayany0_zzZさんの「AR.jsを使って恐竜を家に呼んでみた」です!!
こちら是非ご覧ください!!
参考サイト