セキュリティグループをつくるいろいろ
アカウントを新しく使いはじめる場合や、新しいサブネットを作成したときに、ベースのセキュリティグループをとりあえずセットアップしたいパターンはよくあると思う。 とりあえず、ログインするために、会社のIPからのアクセスを許可するとか。
以下のシナリオを考えてみる。
- ELB + WEBサーバ (EC2)+ DB (RDS) の構成
- Public Subnet, Private Subnetを定義
- 会社のIPからのSSHアクセスを許可する
これを元に以下の構成を考える。
NATインスタンスがいないとか、いろいろあるけど、今回のテーマではないので割愛。
aws cliコマンドライン
まず空のセキュリティグループを作成して、そこにルールを追加する形になる。
- aws ec2 create-security-group コマンドを叩いてセキュリティグループを作成。セキュリティグループIDを取得。
- aws ec2 authorize-security-group-ingressコマンドでIngressのルールを追加
コマンド実行の戻りを変数に入れて、というのがシェルスクリプトだとちょっと面倒です。楽しようと、上では--query
でGroupIdのみ取得していますが、エラーが起きた時のハンドリングができていません。
セキュリティグループを参照したり、変数の嵐となってつらいので上では1個だけ作成しています。
スクリプト (botoの場合)
セキュリティグループをルールに含めたセキュリティグループをつくるのはスクリプト楽ですね。
botoのboto.ec2.securitygroupは、ingress (inbound)前提となっていて、egress (outbound)も使う場合は、
ec2.connectionのauthorize_security_group
、authorize_security_group_egress
あたりを利用することになると思います。
他の各言語のAWS SDKなどでも、Create Security Groupして、そこに対してルールを追加する同様の感じとなります。
- AWS SDK for PHP: authorizeSecurityGroupIngress, createSecurityGroup
- AWS SDK for Ruby: Class: AWS::EC2::SecurityGroup — AWS SDK for Ruby
- AWK SDK for Java: createSecurityGroup
CloudFormation
CloudFormerで作成した例。CloudFormerについてはクラスメソッドさんのブログが分かり易い。
上のようなJSONを生成して、例えばAWS CLIでキックする。
aws cloudformation create-stack --stack-name generate-security-group --template-body file://generate-securitygroup.json
このJSONでは、VPC IDが決め打ちになっているが、もちろんVPC自体も作成できる。
問題点としては、リソース名 (Security Group Name)が、CloudFormationによる自動生成となること。タグで代替できるが、タグは重複を許容するのが、場合によってはあんまりよろしくない。 あと、CloudFormationスタックにセキュリティグループが紐付いているので、スタックを削除すると削除しちゃうので、適宜、Stack Policyを設定する。
まとめ
実際に運用する場合には、VPCと組み合わせて、
- Public Subnet、Private Subnetを定義し、NATインスタンスを起動させる
- 会社側のIP制限ルールのため、踏み台インスタンスを用意してElastic IPを付与したい
とかいろいろあると思う。
こうなってくると、登場人物が増えてくるのと、案件によって変わってきたりして、ちゃんとがっちり構築しようとすると厳しかったりするが、できるところから、ルールが決まっている部分について自動化しておくと、完全な自動構築までの道のりもクリアになる。