なんとかできてるけど,ものすごく変なことしてるような気もするので晒しておく.
Ruby力が足りない
やりたいこと
複数のSecurityGroupに共通で入れるルールを別メソッドなどに切り分けて管理したい.
Groupfile(イメージ)
BASTION_IP = %W(192.0.2.10/32 192.0.2.138/32)
#共通設定(イメージ)
def default_ingress_permissions()
#踏み台サーバからだけSSHを許可する
permission :tcp, 22..22 do
ip_ranges(*BASTION_IP)
end
end
ec2 "vpc-xxxxxxxx" do
security_group "sg1" do
description "sg1"
ingress do
permission :tcp, 80..80 do
ip_ranges("192.0.2.0/24")
end
#ここで呼びたい
default_ingress_permissions()
end
egress do
permission :any do
ip_ranges("0.0.0.0/0")
end
end
end
security_group "sg2" do
description "sg2"
ingress do
permission :tcp, 8080..8080 do
ip_ranges("192.0.2.0/24")
end
#ここで呼びたい
default_ingress_permissions()
end
egress do
permission :any do
ip_ranges("0.0.0.0/0")
end
end
end
end
[ERROR] undefined method `default_ingress_permissions'
と言われて,ingressのblock中でdefault_ingress_permissionsを呼べません.Piculet::DSLのインスタンス内でevalされているのでec2やsecurity_groupのブロック(それぞれ対応するインスタンス内でevalされる?)から呼べない模様.
解決策
見えないなら見える場所においてあげましょう.
- Kernel#module_evalでKernelモジュールにメソッドを定義
- Kernelモジュールからはip_rangesなどのメソッドが呼べないのでProcで返す
Groupfile
Kernel.module_eval {
BASTION_IP = %W(192.0.2.10/32 192.0.2.138/32)
#共通設定
def default_ingress_permissions()
proc {
permission :tcp, 22..22 do
ip_ranges(*BASTION_IP)
end
}
end
}
ec2 "vpc-xxxxxxxx" do
security_group "sg1" do
description "sg1"
ingress do
permission :tcp, 80..80 do
ip_ranges("192.0.2.0/24")
end
binding.pry
#procを実行する
default_ingress_permissions().call
end
egress do
permission :any do
ip_ranges("0.0.0.0/0")
end
end
end
security_group "sg2" do
description "sg2"
ingress do
permission :tcp, 8080..8080 do
ip_ranges("192.0.2.0/24")
end
#procを実行する
default_ingress_permissions().call
end
egress do
permission :any do
ip_ranges("0.0.0.0/0")
end
end
end
end
応用
default_ingress_permissionsは内部でpermissionを実行していますが,security_groupを実行するメソッドを定義して,複数VPC(製品環境と開発環境とか)で使いまわしたりできます.