repl.info

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" {}

ということで、多少短く書けるが、滅茶苦茶短縮できるというほどではなかった。モジュールの管理コストがかかるようになるだけ…かもしれない。