GolangでAWSのセキュリティグループを編集するCLIツールを作成したお話

インフラエンジニアの寺岡です。
今回はGolangでCLIツールを作成したお話です。
名前は「goacl」といいますが、どのようなものかご紹介したいと思います。
1.goaclとは
goaclはGolangで記述されたCLIツールです。
AWSのセキュリティグループの一覧を表示したり
特定のグループに対してルールの追加を行ったりすることが出来ます。
現在は一覧表示とルールの追加のみですが
不要なルールの削除も行えるように機能追加する予定です。
2.作成した理由
社内的/個人的で2つの理由があります。
社内的理由
一言で言うと「将来的にオフィスの固定IPアドレスが変更になるから」が理由です。
弊社内のネットワークの品質をより良いものにするために
回線そのものを変更することが決定したのですが
新しいIPアドレスからのアクセス許可はどうしようとなったわけです。
弊社はMSPを業務の主軸としているため
おかげ様で多数のお客様のAWSアカウントをお預かりしております。
IPアドレスが変更になれば都度全てのアカウントの許可設定を見直す必要があり
手動で許可設定を追加するにはどうしても限界があります。
ここで利用するのが「goacl」です。
個人的理由
以前からGolangを書けるようになりたいと思っていて
業務を効率化すると共に個人的な勉強にもなると考えました。
GolangはTerraformなどのHashiCorpの製品や
kubernetesにも利用されている言語なので
インフラエンジニアでも習得するメリットは充分にあると思います。
3.goaclの使い方とロジック
CLIツールなのでコマンドラインから実行する形になります。
Usage
単純にgoaclと入力するとUsageを確認することができます。
$ goacl
goacl is a CLI tool for listing AWS security groups and adding / deleting rules.
Usage:
goacl [command]
Available Commands:
add Add SecurityGroup rule
help Help about any command
list List SecurityGroup info
Flags:
--config string config file (default is $HOME/.goacl.yaml)
-h, --help help for goacl
-t, --toggle Help message for toggle
Use "goacl [command] --help" for more information about a command.
list
セキュリティグループの一覧を確認することが出来ます。
「list」というサブコマンドを以下のように利用します。
$ goacl list --region us-west-1 --profile default +-------------+-----------+----------+----------------+--------------+ | GROUPID | GROUPNAME | FROMPORT | CIDRIP/GROUPID | VPCID | +-------------+-----------+----------+----------------+--------------+ | sg-XXXXXXXX | default | -1 | sg-XXXXXXXX | vpc-XXXXXXXX | +-------------+-----------+----------+----------------+--------------+
ブログなのでIDの部分はマスクしていますが
goacl内部でaws-sdk-goを利用してセキュリティグループの情報を取得し
実行結果はテーブルに成形されて出力されます。
コマンドのオプションとして
一覧表示するリージョンと利用するプロファイルの指定が可能です。
何も指定しない場合はデフォルト値が参照されて
リージョンが「ap-northeast-1」、プロファイルが「default」になります。
サブコマンドとオプションの実装はcobraを利用しています。
kubernetesのソースコードでも利用されているので割と有名ではないでしょうか。
add
特定のセキュリティグループにルールを追加することが出来ます。
addコマンドを実行する場合はyamlで記述された設定ファイルが必要になります。
rules:
-
groupid: sg-XXXXXXXX
fromport: 80
toport: 80
ipprotocol: tcp
ipranges:
- 0.0.0.0/0
-
groupid: sg-XXXXXXXX
fromport: 443
toport: 443
ipprotocol: tcp
ipranges:
- 0.0.0.0/0
80/443ポートを解放する場合は上記のようになります。
iprangesが許可するIPアドレスになりますが
この項目は複数個記述が可能です。
実際に実行してみましょう。
$ goacl add --region us-west-1 --profile default --config config.yaml $ goacl list --region us-west-1 --profile default +-------------+-----------+----------+----------------+--------------+ | GROUPID | GROUPNAME | FROMPORT | CIDRIP/GROUPID | VPCID | +-------------+-----------+----------+----------------+--------------+ | sg-XXXXXXXX | default | 80 | 0.0.0.0/0 | vpc-XXXXXXXX | + + +----------+----------------+ + | | | -1 | sg-XXXXXXXX | | + + +----------+----------------+ + | | | 443 | 0.0.0.0/0 | | +-------------+-----------+----------+----------------+--------------+
「--config」オプションで設定ファイルの指定が可能です。
後のオプションはlistコマンドと同様です。
addコマンド実行後にlistコマンドを実行すると追加されていることが確認できますね。
ロジックとしては設定ファイルの読み込みにviperを利用しています。
Goのコードの中にyamlの構造と同じ構造体を定義しておき
設定ファイルを読み込んでviper.Unmarshalすることで
構造体にyamlに記述された値を格納しています。
type Config struct {
Rules []Rules `yaml:rules`
}
type Rules struct {
GroupID string `yaml:groupid`
FromPort int64 `yaml:fromport`
ToPort int64 `yaml:toport`
IpProtocol string `yaml:ipprotocol`
IpRanges []string `yaml:ipranges`
}
構造体という考えを実は全く理解していなかったので割と苦戦しましたが
何とか正常に動作してくれるようになりました(もう少し勉強します)
4.まとめ
ひとまず社内で利用してバグの洗い出しをしてからになると思いますが
将来的にOSSとして公開できればと思っています。
まだルールの削除ができないのでそこは引き続き実装してまたブログにまとめます!
0