Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Poolにおける足を止めないシステム基盤構築
Search
Genki Sugawara
May 15, 2022
Technology
8.6k
3
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Poolにおける足を止めないシステム基盤構築
Genki Sugawara
May 15, 2022
More Decks by Genki Sugawara
See All by Genki Sugawara
Hashをめぐる冒険
winebarrel
0
4.2k
Ruby for Iac
winebarrel
0
860
pt-osc的何かとマイグレーションのすりあわせについて
winebarrel
3
1.3k
Elixir Meetup #2 Plugのモジュールを一通り使ってみた
winebarrel
2
1.2k
Other Decks in Technology
See All in Technology
2026-08-05 IBM Z開発最前線!IBM Bob Premium Package for Zって何がすごいの?
yutanonaka
0
120
侵入は突然に 〜 IoTマルウェアと悪用される家庭の機器 ~ / When Intrusion Strikes: IoT Malware and the Abuse of Home Devices
nttcom
0
5.8k
JavaScript 研修 (2026)
recruitengineers
PRO
2
550
名刺メーカーDevグループ 紹介資料
sansan33
PRO
0
1.2k
MIRU 2026 チュートリアル
keisuke198619
0
920
ブラウザ研修 2026
recruitengineers
PRO
6
1k
Bits Agent Builder の⼊⾨と活⽤事例
nulabinc
PRO
0
140
AWS ネットワーク構築でハマった(ハマりかけた) 5選とそこから得た教訓
nagisa53
4
220
ラジオの科学
frievea
0
320
【CEDEC2026】『Relink』を拡張せよ - 『GRANBLUE FANTASY: Relink - Endless Ragnarok』の開発速度と品質を守るCI運用
cygames
PRO
0
180
研究開発部の紹介 / Sansan R&D Profile
sansan33
PRO
4
24k
LLM・AIエージェントシステムベストプラクティス
shibuiwilliam
6
1.3k
Featured
See All Featured
The SEO identity crisis: Don't let AI make you average
varn
0
530
Principles of Awesome APIs and How to Build Them.
keavy
128
18k
BBQ
matthewcrist
89
10k
Building an army of robots
kneath
306
46k
DBのスキルで生き残る技術 - AI時代におけるテーブル設計の勘所
soudai
PRO
68
56k
The World Runs on Bad Software
bkeepers
PRO
72
12k
How Fast Is Fast Enough? [PerfNow 2025]
tammyeverts
3
760
The Power of CSS Pseudo Elements
geoffreycrofte
82
6.5k
Why Mistakes Are the Best Teachers: Turning Failure into a Pathway for Growth
auna
0
200
Design in an AI World
tapps
1
280
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
133
19k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
56
3.4k
Transcript
Poolにおける 開発の足を止めないシステム基盤構築 1
自己紹介 菅原 元気 株式会社カンム SRE @sgwr_dts @winebarrel 好きな技術 / /
/ / は勉強中 2
3
資産運用のハードルを下げる 投資ができるクレカを発行 予定利回り年率1% 決済還元1% https://pool-card.jp/ 4
本日話したいこと 既存のプロダクトで感じていた課題を解決するため コンテナなど社内では使ってこなかった技術スタックを使って Poolのシステム基盤を構築しました。 既存の技術とは大きく異なるシステムで 安全かつスピーディーに開発を行うために意識したところなどを 課題を踏まえながら振り返ります。 5
アジェンダ 決済サービスの簡単な解説 Poolの採用技術 Poolのシステム構成 デプロイ Terraform オペレーション モニタリング まとめ 6
決済サービスの簡単な解説 7
カード関連会社の関係 8
カード利用の流れ 9
オーソリ(仮売上処理)・クリアリング(売上精算) 利⽤者 お店 国際ブランドネットワーク Pool オーソリ カード利⽤ カード利⽤ オーソリ電⽂ オーソリ電⽂
承認 承認 カード利⽤完了 カード利⽤完了 数⽇後 クリアリング 確定売上 確定売上 クリアリング電⽂ クリアリング電⽂ 利⽤者 お店 国際ブランドネットワーク Pool 10
Poolの採用技術 実装(バックエンド) Go インフラ Amazon ECS (Fargate) Amazon Aurora (PostgreSQL)
AWS Step Functions サービス間通信 gRPC 11
Poolの採用技術 CI GitHub Actions モニタリング Datadog インフラ管理 Terraform DBマイグレーション sqldef
12
Poolのシステム構成 13
既存システムの課題 EC2インスタンスの保守 OSのアップデート パッケージのアップデート ログインユーザーの管理 バッチ EC2上でcron Ansibleの適用が手間 →コンテナを中心としたシステムの構築 14
APIサーバ・バッチ 15
オーソリ・クリアリング 16
Poolのサーバ構成 ECS (Fargate) SREの少なさからEKSは不採用 基本的にコンテナ化 オーソリサーバもコンテナ化 クリアリング電文受信のため最低限のEC2(Windowsサーバ) プロビジョニングはPacker Chefにできないか調査中 バッチ処理はStep
Functionsでコンテナ実行 プロダクション・ステージングでAWSアカウントを分けている 17
バッチ Step FunctionsからECSタスクを実行 EventBridgeで定期実行 Windowsバイナリ実行もStep Functions できるだけ処理をAWSに寄せる ワークフローはterraformで定義 EventBridgeと合わせてモジュール化し記述をシ ンプルに
Failした場合、SNS経由でDatadogに通知 18
バッチ resource "aws_sfn_state_machine" "xxx" { name = "xxx" role_arn =
aws_iam_role.state_machine.arn definition = jsonencode({ StartAt = "Run ECS Task", States = { "Run ECS Task" = { Type = "Task" Resource = "arn:aws:states:::ecs:runTask.sync" Parameters = { LaunchType = "FARGATE" EnableExecuteCommand = true NetworkConfiguration = { ... } Cluster = ... TaskDefinition = ... Overrides = { ContainerOverrides = [ { Name = "app" Command = [ ... ] Environment = { ... } }, 19
バッチ module "app_cron" { source = "../modules/cron" name = "app-cron"
cluster_arn = aws_ecs_cluster.app.arn subnet_ids = [for sn in aws_subnet.app : sn.id] definitions = { "batch" = { command = ["./batch-cli", "xxx"] environment = [ { Name = "INPUT_FILE", "Value.$" = "$.INPUT_FILE" }, ] input = { INPUT_FILE = "" } schedule_expression = "cron(5 15 * * ? *)" task_definition = "arn:aws:ecs:ap-northeast-1:123456789012:task-definition/batch" security_groups = [ ... ] task_roles = [ ... ] }, 20
Step Functions AWSのAPIはだいたい何でも実行できる Session ManagerでPowerShellを実行など ワークフローの記述は冗長 待ち合わせ・失敗の処理などに数ステップ必要になる 入出力加工用のJSONPathが貧弱 @ ..
, : ? * がサポートされない 使える関数が限られている HTTPを直接リクエストできない Lambda経由・SNS経由…etc サーバレスのメリットが大きい Step FunctionsのDXは改善したい 21
デプロイ 22
既存システムの課題 テストの実行とデプロイが分離 デプロイは手作業で Ansibleの実行 AMI作成 インスタンスのサービスイン 手間がかかる・ミスが起きる →GitHub Actionsを使ったデプロイの高速化 23
GitHub Actions 24
GitHub Actions 25
テスト・デプロイ GitHub Actions releaseブランチなしのGit Flow masterが直接プロダクションにリリースされる OpenID ConnectでAWSのクレデンシャルを取得 同じワークフローでプロダクション・ステージングを実行 AWS_ACCOUNT:
${{ (github.ref == 'refs/heads/master' && '123456789012') || '210987654321' }} DBマイグレーションはCodeBuild経由で実行 Dockerイメージ不要でVPCにアクセスできるようにするため 26
テスト・デプロイ ECSへのデプロイはecspresso https://github.com/kayac/ecspresso Windowsへのデプロイ CIでビルドしたバイナリをS3にアップロード Session ManagerでWindows上でスクリプトを実行 S3→Windows バッチ用ECSタスク定義 バージョン未指定の場合、latestが実行される
ecspresso run でタスク定義の更新+動作確認 27
ECSタスク定義 / ├── lib │ ├── datadog.libsonnet │ └── utils.libsonnet
├── prd │ ├── pool-app │ │ ├── api │ │ │ ├── ecs-service-def.jsonnet │ │ │ ├── ecs-task-def.jsonnet │ │ │ └── ecspresso.yml │ │ ├── batch │ │ │ └── ... │ │ ├── common │ │ │ ├── api-container.libsonnet │ │ │ └── container-common.libsonnet │ │ └── external-service │ │ └── sendgrid.libsonnet │ └── pool-card │ ├── ... └── stg ├── ... 28
ECSタスク定義 local datadog = import '../../../lib/datadog.libsonnet'; local utils = import
'../../../lib/utils.libsonnet'; local apiCommon = import '../common/api-container.libsonnet'; { containerDefinitions: [ utils.objectToArray(apiCommon { environment+: { USE_CLIENT: 'true', }, secrets+: { CLIENT_SECRET: '{{ tfstate `aws_secretsmanager_secret.secret.arn` }}:secret::', }, logConfiguration: datadog.logConfiguration(...), }), datadog.agentContainer, datadog.fluentBitContainer, ], cpu: '256', executionRoleArn: '{{ tfstate `aws_iam_role.task_execution_role.id` }}', family: 'api', memory: '512', networkMode: 'awsvpc', requiresCompatibilities: ['FARGATE'], taskRoleArn: '{{ tfstate `aws_iam_role.task_role.id` }}', } 29
ECSタスク定義 jsonnetで定義 タイムリーにecspressoがjsonnetサポート https://sfujiwara.hatenablog.com/entry/ecspresso-v1.7.0 Datadog Agentなどのサイドカーや共通部分は.libsonnetに切り出し コードの重複をなくす Terraformリソースの参照はecspressoのtfstateプラグインを利用 直接のIDの記述をなくして可読性を向上 30
リリース 31
リリース 32
リリース @kabot pr-release <repo name> でリリース用PR作成 masterにマージされたらリリース 手作業のミスをなくし、masterに入るPRをわかりやすく Slackボットは自作 Hubotの更新が止まっていたので…
Bolt+Slackソケットモード Hubot/Rubotyの設計を踏襲 PRの作成はボットがgit-pr-releaseを実行 https://github.com/x-motemen/git-pr-release 33
Terraform 34
既存システムの課題 各種インフラリソースがコード化されていない AWS、PostgreSQLロール… リソース管理まわりオペレーションの委譲がしにくい 強力な権限を渡すか、SREが作業する →Terraformによるコード化・作業の委譲 35
Terraform pool/ ├── aws │ ├── modules │ ├── prd
│ │ ├── ecs.tf │ │ ├── rds.tf │ │ ├── s3.tf │ │ └── ... │ └── stg ├── datadog │ ├── prd │ │ ├── moniter.tf │ │ └── ... │ └── stg ├── pagerduty │ └── prd │ ├── service.tf │ └── ... └── postgresql ├── prd │ ├── app-db │ │ ├── app_user.tf │ │ └── ...terraform.tf │ └── card-db └── stg 36
Terraform Pool以外のサービスのTerraformも含まれるモノレポ AWSに限らずDatadog/PagerDuty/PostgreSQLも管理 モジュールはなるべく使わない方針 コードを追いやすい リソースの相互参照がしやすい リソースの変更を局所化できる 環境ごとのコードの記述量が多くなるのが課題 記述量の削減のために for_each
を積極的に使用 37
Terraform resource "aws_subnet" "pool" { for_each = { ap-northeast-1a =
"10.50.0.0/24", ap-northeast-1b = "10.50.1.0/24", } vpc_id = aws_vpc.pool.id cidr_block = each.value availability_zone = each.key tags = { Name = "pool-${each.key}" } } resource "aws_route_table" "pool" { for_each = aws_subnet.pool vpc_id = aws_vpc.pool_app_prd.id } resource "aws_route_table_association" "pool" { for_each = aws_subnet.pool subnet_id = each.value.id route_table_id = aws_route_table.pool[each.value.availability_zone].id } 38
Terraform PRで terraform plan だけGitHub Actionsで実行 結果はPRにコメント 開発者がPR経由でリソースの変更の提案を行える applyはSREが手動で実行 terraform
apply の自動化は課題 ステージング環境については開発者にapply可能な権限を付与 ステージング環境は開発者が自由に操作できる 39
オペレーション 40
既存システムの課題 基本的には管理画面での操作 まれにCLIを操作するオペレーションが発生する 管理用コマンドの実行 ネットワークの疎通確認 どうしても必要なDBの操作 サービスコンテナへのECS Exec セキュリティ上よくない オペレーション用EC2インスタンス
管理コストがかかる →demitasというツールを作成 41
demitas 42
demitas https://github.com/winebarrel/demitas https://tech.kanmu.co.jp/entry/2021/12/14/100000 ecspressoのラッパー サービスと同じVPC・サブネット・SGで作業用タスクを起動 作業が終わったらタスクは破棄 コンテナ経由のポートフォワーディングも可能 kubectl run kubectl
port-forward をイメージして作成 43
demitas $ demitas-exec -e bash Start ECS task... ECS task
is running: 9b71b0c7e090f7e0ac8a7bc4fbf051a7 The Session Manager plugin was installed successfully. Use the AWS CLI to start a session. Starting session with SessionId: ecs-execute-command-5daee3efe79819c1 root@ip-10-50-0-10:/# 44
demitas サービスのコンテナにログインすることなくVPC内作業が可能 使い捨てのコンテナなので自由にパッケージを入れられる タイミングによってはECSタスクが残ったままになる クリーニングが課題 実装がきれいではないのでリファクタリングしたい 45
モニタリング 46
既存システムの課題 通知や情報が分散している ログがEC2サーバ上 Slackチャンネルへの通知、PagerDutyへの通知 SaaSが分散している Sentry、Mackerel →Datadogによる一元管理 47
モニタリング 基本的にDatadog 一部PagerDuty モニターはTerraformで管理 閾値の変更が誰でもしやすくなる ログもDatadogに送信 Live Tailも可能でログの検索性が向上 APMやエラートラッキングとの紐付けで調査がしやすく Datadogの保持期間以上はS3に
48
アラート PagerDutyとSlackに通知 すべてのアラートはPagerDutyでインシデント化 アラートのアサイン漏れを防ぐ 緊急度の高くないものはLow Urgencyで Log Urgencyはoncall-statusでOS Xのデスクトップに通知 https://github.com/mtougeron/oncall-status
通知メッセージにはRunbookのリンクを含める 誰でもインシデントに対応できるように 49
まとめ システム構成 コンテナ化で管理コストの削減 デプロイ GitHub Actionsでのデプロイの高速化 Terraform コード化による適切な作業の委譲 オペレーション demitasによる安全で自由度の高い作業の実現
モニタリング Datadogでの一元管理やアラートの集約で効率化 50
We are hiring! https://team.kanmu.co.jp/ 51