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

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

Leave a Reply

Your email address will not be published. Required fields are marked *