AWS環境をTerraformで構築する機会がありましたので、やったことをメモしておきたいと思います。
1、AWSCLIのインストール
以下のリンクを参照して、対応するOS用のAWSCLIをインストールします。
2、AWSの認証情報設定
認証情報の設定方法は、以下のように複数あります。
- EC2インスタンスに適切なアクセス権限が付いたIAMロールを設定する。
- AWSCLIの「aws configure」コマンドを使用し、認証情報を登録する。
- Terraformファイルの中に直接設定する。
今回は、「aws configure」コマンドを使用する方法で、認証情報を設定します。
2-1、アクセスキー・シークレットキーの発行
AWSのWEBコンソールでアクセスキーとシークレットキーを発行します。
2-2、AWSCLIへの認証情報登録
生成されたアクセスキーとシークレットキーを以下のコマンドで登録します。
# aws configure --profile hogehoge ※--profileは無くてもOK
AWS Access Key ID [None]:(例: AKIAIOSFODNN7EXAMPLE)
AWS Secret Access Key [None]:(例: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY)
Default region name [None]:<なし>
Default output format [None]:<なし>
3、Terraformのインストール
Terraformのインストールは、Terraformを直接インストールするのではなく、tfenvを使用してインストールします。
このようにすることで、terrafomeのバージョン管理を容易に行うことが出来ます。(作業ディレクトリごとにバージョンを変えたい場合などに便利です。)
3-1、tfenvのインストール
以下のリンクに従ってインストールします。
https://github.com/tfutils/tfenv
※Macにインストールする場合は、以下のコマンドを実行します。
brew install tfenv
3-2、Terraformのインストール
最新バージョンのTerraformをインストールする場合は、以下のコマンドを実行します。
tfenv install latest
4、AWS環境の構築
4-1、作業用ディレクトリの作成
作業用のディレクトリを作成します。作成場所は自分の好きな場所で構いません。私は、以下のディレクトリに作成しました。
mkdir -p /home/<ユーザー名>/work/terraform-test
cd /home/<ユーザー名>/work/terraform-test
4-2、Terraformの初期化
1、ディレクト内で以下内容のファイルを作成します。
<provider.tf>
provider "aws" {
region = "ap-northeast-1"
profile = "hogehoge" #なくてもOK
}
#※ファイル名は*.tfの形式であれば自動的に読み込まれます。
2、ファイル作成後、provider.tfファイルがあるディレクトリで「terraform init」コマンドを実行します。
$ terraform init
Initializing the backend...
Initializing provider plugins...
- Checking for available provider plugins...
- Downloading plugin for provider "aws" (hashicorp/aws) 2.66.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 = "~> 2.66"
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.
4-3、AWS環境の構築
provider.tfファイルがあるディレクトリで、以下の様な内容でファイルを作成していきます。オプションなどの詳細は、以下のリンクを参照します。
ファイル作成後、構文チェックなどの動作テストを行う場合は、「terraform plan」コマンドを実行します。
$ 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_vpc.vpc-01 will be created ← 実際に構築した際にどのような動作をするか表示される。
+ resource "aws_vpc" "vpc-01" {
+ arn = (known after apply)
+ assign_generated_ipv6_cidr_block = false
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
省略
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
------------------------------------------------------------------------
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.
各ファイルの記述例は以下の通り。
<variables.tf>
variable "pj_name" {
type = "map"
default = {
name = "test-nakamura"
}
}
variable "common-AZ" {
type = "map"
default = {
region = "ap-northeast-1"
az-1 = "ap-northeast-1a"
az-2 = "ap-northeast-1c"
az-3 = "ap-northeast-1d"
}
}
variable "key_name" {
type = "map"
default = {
key = "nakamura-ryo"
}
}
<vpc.tf>
resource "aws_vpc" "vpc-01" {
cidr_block = "10.0.0.0/16"
enable_dns_support = "true"
enable_dns_hostnames = "true"
tags = {
Name = "${var.pj_name["name"]}-vpc"
}
}
<igw.tf>
resource "aws_internet_gateway" "igw-01" {
vpc_id = "${aws_vpc.vpc-01.id}"
tags = {
Name = "${var.pj_name["name"]}-igw01"
}
}
<subnet.tf>
resource "aws_subnet" "public-subnet-1" {
cidr_block = "${cidrsubnet(aws_vpc.vpc-01.cidr_block, 8, 0)}"
vpc_id = "${aws_vpc.vpc-01.id}"
availability_zone = "${var.common-AZ["az-1"]}"
tags = {
Name = "${var.pj_name["name"]}-public-az-a"
}
}
<rt.tf>
resource "aws_route_table" "vpc-public-rtb" {
vpc_id = "${aws_vpc.vpc-01.id}"
route {
cidr_block = "0.0.0.0/0"
gateway_id = "${aws_internet_gateway.igw-01.id}"
}
tags = {
Name = "${var.pj_name["name"]}-public-rtb"
}
}
<rta.tf>
resource "aws_route_table_association" "public-subnet-1" {
subnet_id = "${aws_subnet.public-subnet-1.id}"
route_table_id = "${aws_route_table.vpc-public-rtb.id}"
}
<sg.tf>
resource "aws_security_group" "sg-common" {
vpc_id = "${aws_vpc.vpc-01.id}"
name = "${var.pj_name["name"]}-sg-common"
description = "${var.pj_name["name"]}-sg-common"
tags = {
Name = "${var.pj_name["name"]}-sg-common"
}
#IPを指定するルール
ingress {
description = "hoge"
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["123.123.123.123/32"]
}
#自分自身を許可するルール
ingress {
self = "true"
from_port = 0
to_port = 0
protocol = -1
}
#SGIDを指定するルール
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
security_groups = [aws_security_group.sg-elb01.id]
}
#アウトバウンド通信の許可ルール
egress {
from_port = 0
to_port = 0
protocol = -1
cidr_blocks = ["0.0.0.0/0"]
}
}
<ec2.tf>
resource "aws_instance" "web01" {
ami = "ami-xxxxxxxxxxxxxxxxx"
instance_type = "t2.micro"
key_name = "${var.key_name["key"]}"
subnet_id = "${aws_subnet.protected-subnet-1.id}"
iam_instance_profile = "hogehoge"
vpc_security_group_ids = [
"${aws_security_group.sg-common.id}",
"${aws_security_group.sg-web01.id}"
]
tags = {
Name = "${var.pj_name["name"]}-web01"
}
}
<elb.tf>※ClassicELBの設定方法
resource "aws_elb" "elb-01" {
name = "${var.pj_name["name"]}-elb01"
subnets = ["${aws_subnet.public-subnet-1.id}", "${aws_subnet.public-subnet-2.id}"]
security_groups = ["${aws_security_group.sg-elb01.id}"]
listener {
instance_port = 80
instance_protocol = "http"
lb_port = 80
lb_protocol = "http"
}
listener {
instance_port = 80
instance_protocol = "http"
lb_port = 443
lb_protocol = "https"
ssl_certificate_id = "arn:aws:iam::123456789012:server-certificate/certName"
}
health_check {
healthy_threshold = 5
unhealthy_threshold = 2
timeout = 5
target = "TCP:80"
interval = 30
}
instances = ["${aws_instance.web01.id}", "${aws_instance.web02.id}"]
cross_zone_load_balancing = true
idle_timeout = 60
connection_draining = true
connection_draining_timeout = 400
tags = {
Name = "${var.pj_name["name"]}-elb"
}
}
4-4、AWS環境へのデプロイ
各種ファイルへの記述が終了し、AWS環境を実際に構築する場合は、「terraform apply」コマンドを実行します。
※「terraform plan」コマンド実行時にエラーが発生しなくても、AWS環境構築時にエラーが発生する場合があります。
その場合は、エラー箇所修正後、再度「terraform apply」コマンドを実行します。
4-5、AWS環境の削除
構築したAWS環境が不要になった場合は、「terraform destroy」コマンドを実行し、環境を削除します。
“terraformの基本的な使い方メモ” への1件のフィードバック