openstack_networking_secgroup_v2、openstack_networking_secgroup_rule_v2の冗長さをどうにかできないか試した
TerraformでOpenStackのセキュリティグループとルールを定義していると、結構ダラダラと長くなってしまい、あまり見やすくないなあと思うことが増えてくる。
resource "openstack_networking_secgroup_v2" "security_group" {
name = "secgroup_1"
description = "My neutron security group"
}
resource "openstack_networking_secgroup_rule_v2" "rule_1" {
direction = "ingress"
ethertype = "IPv4"
protocol = "tcp"
port_range_min = 80
port_range_max = 85
remote_ip_prefix = "0.0.0.0/0"
security_group_id = "${openstack_networking_secgroup_v2.security_group.id}"
}
resource "openstack_networking_secgroup_rule_v2" "rule_2" {
direction = "ingress"
ethertype = "IPv4"
protocol = "tcp"
port_range_min = 22
port_range_max = 22
remote_ip_prefix = "0.0.0.0/0"
security_group_id = "${openstack_networking_secgroup_v2.secrity_group.id}"
}
それぞれ1つだけなら気にならないのだけど、セキュリティグループが10とか20になり、それぞれのルールも似たようなものが大量にある、となると1ファイルではとうていやっていられない。セキュリティグループ毎にディレクトリを分けるというのも1つの手だが、モジュールでいい感じに省略できないか試した。
なお、Terraformのバージョンは v0.9.10 を使用。
構成としては以下のようになる。セキュリティグループと、イングレス用のルールそれぞれをモジュールにした。
.
├── main.tf
├── modules
├── security_group
│ ├── main.tf
│ ├── output.tf
│ └── variables.tf
└── security_group_rule_ingress
├── main.tf
└── variables.tf
トップレベルのmain.tfは以下の通り。ルールのdirectionやethertype、protocolなどほぼ共通するものをモジュールで吸収して、ポートやCIDR、セキュリティグループのIDといった個別の要素のみを記述する、という形。が、行数だとあまり変わらないね… sourceの入力が必要だったりするからなあ。
module "security_group" {
source = "./modules/security_group"
name = "secgroup_1"
description = "My neutron security group"
}
module "rule_1" {
source = "./modules/security_group_rule_ingress"
port_range_min = 80
port_range_max = 85
cidr = "0.0.0.0/0"
security_group_id = "${module.security_group.id}"
}
module "rule_2" {
source = "./modules/security_group_rule_ingress"
port = 22
cidr = "0.0.0.0/0"
security_group_id = "${module.security_group.id}"
}
次はセキュリティグループモジュール。運用によってはdescriptionもnameから生成するなどして入力不要にできるかもしれない。
main.tf
resource "openstack_networking_secgroup_v2" "secgroup" {
name = "${var.name}"
description = "${var.description}"
}
variable.tf
variable "name" {}
variable "description" {}
output.tf
output "id" {
value = "${openstack_networking_secgroup_v2.secgroup.id}"
}
そしてセキュリティグループルール。変数としてportを指定した場合はminとmaxどちらもその値を使う、というようにしてみた。22番や80番を許可する場合はすっきり書けるのではないか。
main.tf
resource "openstack_networking_secgroup_rule_v2" "rule" {
direction = "ingress"
ethertype = "IPv4"
protocol = "tcp"
port_range_min = "${var.port != "false" ? var.port : var.port_range_min}"
port_range_max = "${var.port != "false" ? var.port : var.port_range_max}"
remote_ip_prefix = "${var.cidr}"
security_group_id = "${var.security_group_id}"
}
variables.tf
variable "port_range_min" {
default = false
}
variable "port_range_max" {
default = false
}
variable "port" {
default = "false"
}
variable "cidr" {}
variable "security_group_id" {}
ということで、多少短く書けるが、滅茶苦茶短縮できるというほどではなかった。モジュールの管理コストがかかるようになるだけ…かもしれない。