いつも、CloudFormation で構築しているが、今回は、学習のために、Terraform で構築してみた。
Terraform の導入
以下、Terraform のサイトから、各OSにあったものをインストールする。
今回は、Cloud9 (Amazon Linux2) で実行しています。
$ sudo yum install -y yum-utils
$ sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/AmazonLinux/hashicorp.repo
$ sudo yum -y install terraform
$ terraform version
Terraform v1.3.1
on linux_amd64
作業ディレクトリの作成
$ mkdir Teraform
$ cd Teraform/
provider の指定
provider "aws" {
region = "ap-northeast-1"
}
保存先の指定
terraform {
backend "s3" {
bucket = "<S3バケット名>"
key = "path/terraform.tfstate"
region = "ap-northeast-1"
}
}
Teraform への権限
- IAMユーザーの認証情報
- IAMロール
resource構文
ドキュメントを参考に、デプロイするリソースを記述します。
環境変数(var)になっている部分の説明については後述する、Variable構文 をご確認ください。
関連するリソースについては、vpc_id = aws_vpc.vpc.id
のように記述します。
resource "aws_vpc" "vpc" {
cidr_block = var.vpc_cidr[var.env]
enable_dns_hostnames = true
tags = {
Name = "&(var.env)-$(var.project)-vpc"
}
}
resource "aws_subnet" "pubric_a" {
vpc_id = aws_vpc.vpc.id
cidr_block = var.subnet_cidr[var.env]
availability_zone = var.az["az_a"]
map_public_ip_on_launch = true
tags = {
Name = "&(var.env)-$(var.project)-pubric-a-subnet"
}
}
resource "aws_internet_gateway" "igw" {
vpc_id = aws_vpc.vpc.id
tags = {
Name = "&(var.env)-$(var.project)-igw"
}
}
resource "aws_route_table" "pubric" {
vpc_id = aws_vpc.vpc.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.igw.id
}
tags = {
Name = "&(var.env)-$(var.project)-pubric-rtb"
}
}
resource "aws_route_table_association" "pubric_a" {
subnet_id = aws_subnet.pubric_a.id
route_table_id = aws_route_table.pubric.id
}
resource "aws_instance" "ec2" {
ami = "ami-078296f82eb463377"
instance_type = "t2.micro"
subnet_id = aws_subnet.pubric_a.id
}
output "ec2_public_ip" {
value = aws_instance.ec2.public_ip
}
Variable構文
string
値を単一文字列として使う。
variable "変数名" {
type = string
default = "xxx"
{
list
値を配列として使う。
variable "変数名" {
type = list
default = ["xxx", "yyy"]
{
map
値と文字列に紐づけて使う。
variable "変数名" {
type = map
default{
aaa = "xxx"
bbb = "yyy"
}
{
次にような記述ができると思います。
variable "vpc_cidr" {
type = map(string)
default = {
prd = "10.1.0.0/16"
dev = "10.2.0.0/16"
}
}
variable "subnet_cidr" {
type = map(string)
default = {
prd = "10.1.1.0/24"
dev = "10.2.2.0/24"
}
}
variable "az" {
type = map(string)
default = {
az_a = "ap-northeast-1a"
az_c = "ap-northeast-1c"
}
}
variable "project" {
type = string
default = "test"
}
variable "env" {
type = string
default = "dev"
}
init
ここまでの必要なファイルを纏めるとつぎのような構造になると思います。
├── terraform
│ ├── develop
│ │ ├── terraform.tf
│ │ └── variable.tf
│ │ └── vpc.tf
│ │ └── ec2.tf
作業ディレクトリ(develop)で、init コマンドを実行し、初期化する。
$ terraform init
Initializing the backend...
Successfully configured the backend "s3"! Terraform will automatically
use this backend unless the backend configuration changes.
Initializing provider plugins...
- Finding latest version of hashicorp/aws...
- Installing hashicorp/aws v4.33.0...
- Installed hashicorp/aws v4.33.0 (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.
plan
作成されるリソースが表示されます。※.tfファイルの構文やリソースの設定に問題がある場合はErrorとなります。
$ terraform plan
apply
terraform apply
コマンドを実行し、yes
を入力することでデプロイされていきます。
$ 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
Apply complete! Resources: 6 added, 0 changed, 0 destroyed.
Outputs:
ec2_public_ip = "X.X.X.X"
環境複製方法
次のように、production ディレクトリを作成し、variable.tf ファイルで、env
を prod
にし、後は、develop と同様に、init、plan、apply することでデプロイされます。
├── terraform
│ ├── develop
│ │ ├── terraform.tf
│ │ └── variable.tf
│ │ └── vpc.tf
│ │ └── ec2.tf
│ ├── production
│ │ ├── terraform.tf
│ │ └── variable.tf
│ │ └── vpc.tf
│ │ └── ec2.tf
variable "env" {
type = string
default = "prod"
}
削除
terraform destroy
コマンドを実行し、yes
とすることで削除が完了します。
$ terraform 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