Slide 1

Slide 1 text

© DMM.com Go初心者がAWSの チェックツール作ってみた 〜社内AWSガイドラインのチェック自動化に向けて〜 ITインフラ本部 SRE部 湯浅省吾 更新:2022/12/13

Slide 2

Slide 2 text

© DMM.com 今回お話すること AWS設定内容を自動でチェックするツール作ったお話です 2 ツール作成の経緯や、開発の際に感じたことをお話します X ※ Amazon Web Services、"Powered by AWSロゴ"、[およびかかる資料で使用されるその他の AWS商標]は、米国その他の諸国における、 Amazon.com Inc. またはその関連会社の商標です。

Slide 3

Slide 3 text

© DMM.com 自己紹介 ● 名前 : 湯浅 省吾(ゆあさ しょうご) ● 所属 : SRE部(2019年 6月に入社) ● 前職: SIerでコンテナとかJenkinsとかAnsibleとか ● DMMに来てからのお仕事: • オンプレからAWSへの移行 • 自動化、IaC、モニタリングなど • 現在はオンラインサロンや物販事業部の支援

Slide 4

Slide 4 text

© DMM.com みなさんはAWSの設定内容の チェックをどうしてますか? 4

Slide 5

Slide 5 text

© DMM.com よりよいAWS設定を行うための社内施策 SRE部ではAWSの設定内容をチェックするアセスメント サービスを社内に提供している 5 さらに社内の案件支援で溜まったAWSの知見をガイドライン化 して社内に公開している 推奨設定の紹介 実際の環境をチェック ガイドライン アセスメント

Slide 6

Slide 6 text

© DMM.com クラウドガイドライン 社内の案件支援で溜まったAWSの知見をガイドライン化 6 一般論だけでなく、数多くのサービスを展開している弊社だからこそ 得られた知見や、障害事例を踏まえた内容を記載 アセスメント実施する際は、クラウドガイドラインの内容も 踏まえてアセスメントを実施

Slide 7

Slide 7 text

© DMM.com クラウドガイドライン 7 対象サービスとしては、社内でよく使われているものから記載しており、 今後、随時拡充していく予定(ALB、ECS、Auroraなどなど) ガイドラインの詳しい中身に関しては今回は触れない

Slide 8

Slide 8 text

© DMM.com AWSアセスメント 社内向けにAWSの内容をSRE部がアセスメント 8 アセスメント結果はレポート資料として還元 サンプル

Slide 9

Slide 9 text

© DMM.com AWSアセスメント 9 サンプル

Slide 10

Slide 10 text

© DMM.com アセスメントでのチェックにおける課題 10 アセスメント担当者が毎回目視でAWSアカウントに入ってチェック ❏ サービス規模やAWSリソースの数によっては数時間〜1,2日かかる 機械的にチェックできる項目に関しては自動化できるのでは? 「自動化できそうだし、やってみるか!」

Slide 11

Slide 11 text

© DMM.com ツールを作るにあたって何をつかうべき? 11 シェルスクリプト → お手軽に作れるけどシェル芸になりそう → Windows で動かそうとすると面倒なのでは? AWS configでのカスタムルール → まずは作ってみる・小さく始めるにはハードル高そう → チェックするたびに費用がかかる Go or Python? → 作るにあたっては、どちらもでOK → KubernetesやTerraformなど、SREが触れるツールでGo実装も多く、  初心者でも開発しやすいという話もよく聞く         「よし!Goで作ってみるか!」

Slide 12

Slide 12 text

© DMM.com なにはともあれ、作ってみた 12

Slide 13

Slide 13 text

© DMM.com ツールのディレクトリ構成 13 ├── Dockerfile ├── README.md ├── cmd │ └── main.go ... ツール実行の起点となる go スクリプトファイル ├── configs │ └── config.ini ... 出力先ディレクトリ設定等のパラメータファイル ├── go.mod ├── go.sum ├── output ... チェック結果のCSV出力用ディレクトリ └── services ... AWSサービスに応じた go スクリプト ├── account.go ├── acm.go ├── ebs.go │ : │ : └── vpc.go

Slide 14

Slide 14 text

© DMM.com 実装イメージ(起点となる処理) 14 // 各種パラメータ用のConfigファイル読み込み commonCfg, err := ini.Load("configs/config.ini") // 認証情報の取得 awsCfg := loadAwsConfig() // AWS check resultList, accountId := check(awsCfg) // csv出力 csvPath := commonCfg.Section("").Key("csv_path").String() + "/aws-check-" + accountId + ".csv" writeCheckResultCsv(resultList, csvPath) AWSの認証情報については環境変数に 事前に設定しておけばそれを利用してくれる # ツール実行する前に、認証情報を OS環境変数に設定しておく export AWS_ACCESS_KEY_ID=< アクセスキー > export AWS_SECRET_ACCESS_KEY=< シークレットキー > export AWS_REGION=ap-northeast-1

Slide 15

Slide 15 text

© DMM.com 実装イメージ(チェックロジックの親関数) 15 func check(awsCfg aws.Config) ([]*services.CheckResult, string) { resultList := []*services.CheckResult{} //////// VPC(これ以外の各種サービスも同じ様にチェック、出力) // チェック実行 resultVpc, err := services.CheckVpc(awsCfg) // チェック結果格納用の構造体リストに、結果をどんどん追加していく resultList = append(resultList, resultVpc...)   // チェック結果を出力 vpcCountTotal := countTotalCheck(resultVpc) printResultCount(vpcCountTotal)

Slide 16

Slide 16 text

© DMM.com 実装イメージ(各サービスでのチェック) 16 // S3系チェック用の親関数 func CheckS3(cfg aws.Config) ([]*CheckResult, error) { fmt.Println("- S3チェック実行 ...") client := s3.NewFromConfig(cfg) s3InfoMap, err := getS3Info(client) return execS3Checker(s3InfoMap), err } // S3系チェックに必要な情報取得関数 func getS3Info(client *s3.Client) (map[string]*S3Info, error) { s3ListInput := &s3.ListBucketsInput{} s3ListOutput, err := client.ListBuckets(context.TODO(), s3ListInput) client := <サービス>.NewFromConfig(cfg) としてAWSクライアントを生成・取得すれば 各種サービスで情報取得できるようになる client.<情報取得関数> という形で任意の関数を 呼び出せば、情報取得が可能 取ってきた値を、後続処理で if文使ってチェックしていく

Slide 17

Slide 17 text

© DMM.com AWS SDKではCLIと同じような情報が取れる 17 # AWS CLI で インスタンス情報取得したとき $ aws ec2 describe-instances { "Reservations": [ { "Groups": [], "Instances": [ { "AmiLaunchIndex": 0, "ImageId": "ami-xxxxxxxxxx", "InstanceId": "i-xxxxxxxxxxxxxx", "InstanceType": "t2.large", "KeyName": "hogehoge.pem", "LaunchTime": "2022-04-11T07:08:47+00:00", "Monitoring": { "State": "disabled" }, // EC2情報の取得 ec2Input := &ec2.DescribeInstancesInput{} ec2Output, err := client.DescribeInstances(context.TODO(), ec2Input) ec2InfoMap := map[string]*Ec2Info{} for _, reservation := range ec2Output.Reservations { // インスタンスごとの情報取得 if reservation.Instances != nil { for _, ec2 := range reservation.Instances { ec2InfoMap[*ec2.InstanceId] = &Ec2Info{} ・CLIだとJSONで返却されてくるような値が、 SDKだとオブジェクトとして返却 ・リストやオブジェクトで階層構造になってるので、ループ処理で欲しい値を掘り出してくる ・取得した情報を元に、 if文で設定内容をチェックして OK/NGを返す

Slide 18

Slide 18 text

© DMM.com 実行結果イメージ 18 ##### 実行結果標準出力サンプル ##### ### AWS チェックSTART ### - Accountチェック実行 ... === サービスごとのチェック状況 === - VPCチェック実行 ... Check OK: 9 Check NG: 1 - 優先度高: 0 - 優先度中: 1 - 優先度低: 0 ・・・(中略)・・・ - Quotaチェック実行 ... Check OK: 1 Check NG: 0 === チェック全体結果 === Check OK: 18 Check NG: 29 - 優先度高: 0 - 優先度中: 29 - 優先度低: 0 ### AWS チェックFinished ### - チェック結果は ./output/aws-check.csv に出力されました - サービスごとのチェック結果 OK/NG数と 全体でのOK/NG数を表示 詳細については、CSVに出力 チェックしている各ケースごとに優先度を 設定できるようにしているので、必要に応じて 優先度付けが可能 → チェックNGのうち優先度高いものから対応していく

Slide 19

Slide 19 text

© DMM.com ツールのパッケージング(Go Releaser) 19 name: release on: push: tags: - "v*" jobs: release: runs-on: ubuntu-22.04 container: golang:1.19.0-bullseye steps: - name: checkout uses: actions/checkout@v3 with: fetch-depth: 0 - name: Run GoReleaser uses: goreleaser/goreleaser-action@v3 with: distribution: goreleaser version: latest args: release --rm-dist env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} Github Actions でこのようにyamlを用意すると Mac/Windows/Linuxといった複数環境に対応した バイナリが生成できる

Slide 20

Slide 20 text

© DMM.com 作ってみてどうだったか(全般) ツール化した結果、1分もかからずチェックできるようになった ❏ パッケージ配布のためのビルドも簡単だった 20 Go使うのが初めてだったので、文法を覚えたりする時間は必要だったが 特別難しいわけではない 気軽に作成することができたので、全体としてはよかった

Slide 21

Slide 21 text

© DMM.com 作ってみてどうだったか(AWS SDKの話) 21 AWS SDK Go が v1 と v2 があり、使い方が微妙に違うので注意が必要 ❏ 今回はv2を使っているが、情報調べるとv1での実装例がヒットしたり AWS SDK で取得した情報を使う時に、マメにnullチェックが必要 ❏ 未設定パラメータの中身が「空文字」だったり「null」だったりする ❏ 「空文字」だと思って「null」に触って、ぬるぽ発生

Slide 22

Slide 22 text

© DMM.com 今後に向けて 22 SRE部がメインで利用するツールにとどまっているので、CircleCI等 で定期実行できるようにしていきたい ツールが社外公開できると嬉しいかも(すいません、そのへんは未定です

Slide 23

Slide 23 text

© DMM.com ご清聴ありがとうございました 23