この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
こんにちは、コンサル部の島川です。
今回はTerraformのModule間の受け渡しについてAWSを例に説明します。コマンド一発で環境が作れるのは幸せを感じます。
Moduleのイメージ
Moduleはパーツのように扱うことができます。組み合わせ無限大です。使いたいものだけを使えばOKです。
また、Moduleで区切ることで依存関係をスッキリさせることもできます。
Module間の値のやり取り
ただし、VPCのModule書いて、EC2のModule書いて起動!と簡単にはいきません。EC2を作成する際にサブネットIDを指定する必要があり、それは一度VPCを作らないと分からないです。自動補完したいですよね。Terraformには出力された値を他のModuleで参照できる方法があります。
出力された値をOutput Valuesとして明示的に書いておくと他のModuleさんも使えるようになります。また、OutputはModuleの中に書いてあげる必要があります。
Outputの宣言例
output "instance_ip_addr" {
value = aws_instance.server.private_ip
}
- instance_ip_addrが変数名です。なんでもOKです。
- valueが変数に格納される値です。例ではサーバのプライベートIPを格納しています。
基本的にはこちらの宣言のみですが、他にもオプションがあります。
オプション | 概要 |
---|---|
description | 概要を書く |
sensitive | CLIへの出力を抑制する(機密情報をマスクしたいときに使用) |
depends_on | 値の出力に依存関係の指定がある場合に使用する。最後の手段といわれていて積極的に使うものではない。 |
全て書くと以下のようになります。
output "instance_ip_addr" {
value = aws_instance.server.private_ip
description = "The private IP address of the main server instance."
sensitive = true
depends_on = [
# Security group rule must be created before this IP address could
# actually be used, otherwise the services will be unreachable.
aws_security_group_rule.local_access,
]
}
補足ですが、valueはlist形式でもOKです。
他のModuleの値を参照する
Outputに出力された値を他のModuleが参照するにはmodule.
の形式で使用します。Module NAMEが「hogeserver」でOutputの値がinstance_ip_addrならmodule.hogeserver.instance_ip_addr
のように書いてあげます。
簡単な例を用いて説明します。
例
ModuleはVPCとEC2の二つを使います。EC2作成時にVPCのModuleで作られたサブネットIDを指定したいという状況です。
今回使用するModuleはTerraform Registryのものを使用します。Terraform Registory?についてはこちら参照ください。
Terraform Registory
今回使用するTerraform Registoryです。
サンプルコード
1つのファイルにまとめてあります。
main.tf
//----------
//Provider
//----------
provider "aws" {
region = var.aws_region
}
variable "aws_region" {
default = "ap-northeast-1"
}
//----------
//variable
//----------
variable ec2_name {
default = "hoge-server"
}
//----------
//VPC Config
//----------
module "vpc" {
source = "../modules/VPC/terraform-aws-vpc"
name = "hoge-vpc"
cidr = "10.10.0.0/16"
env = "test"
azs = ["ap-northeast-1a", "ap-northeast-1c"]
public_subnets = ["10.10.0.0/24", "10.10.1.0/24"]
private_subnets = ["10.10.10.0/24", "10.10.11.0/24"]
enable_nat_gateway = false
single_nat_gateway = false
}
//----------
//EC2 config
//----------
data aws_ssm_parameter amzn2_ami_latest {
name = "/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2"
}
module "hoge-server" {
source = "terraform-aws-modules/ec2-instance/aws"
version = "~> 2.0"
name = var.ec2_name
instance_count = 1
ami = data.aws_ssm_parameter.amzn2_ami_latest.value
instance_type = "t3.micro"
key_name = "ec2testkey"
monitoring = false
subnet_id = module.vpc.private_subnets[0]
//private_ip = ""
ebs_optimized = true
root_block_device = [
{
delete_on_termination = true
encrypted = true
iops = 60
kms_key_id = ""
volume_size = 20
volume_type = "gp2"
},
]
tags = {
Name = var.ec2_name
}
}
57行目でVPC Moduleで出力された値を参照しています。今回、PublicSubnet2つとPrivateSubnet2つと複数作成しておりますので、list形式で出力されているため配列番号を指定しております。今回だとCIDR「10.10.10.0/24」のもののIDを指定している形になります。
Outputはどこで指定した?
Terraform RegistoryのModuleはOutputもきちんと書いてくれています。指定できるOutputの値もまとまってあります。
VPCだとここです。private_subnetsで指定できるのが分かります。
さいごに
TerraformのModule間のやり取りを説明しました。依存関係を分離できるので色んなModuleを組み合わせて使っていきたいですね。
Terraform Registoryめっちゃ便利じゃないですか?(これを伝えたかった)