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
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
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.1k
Other Decks in Technology
See All in Technology
【2026年版】 ベクトル検索䛸 Embedding最前線
mocobeta
2
220
作って終わりにしない タイミーのセマンティックレイヤー育成の現在地
chanyou0311
4
2.4k
Claude Codeをどのように キャッチアップしているか
oikon48
13
8.2k
日本 Fintech 未来予測レポート 2027〜2028年(手動編集版)
8maki
0
2.3k
エンジニアリング戦略の作り方 / Crafting Engineering Strategy
iwashi86
21
7k
SONiCの統計情報を取得したい
sonic
0
180
マルチアカウント環境での コーディングエージェントを使った障害調査が大変なので AIエージェントにReadOnly権限を付与してみた / ReadOnly AI Agents for Multi-Account AWS Incident Response
yamaguchitk333
2
110
2026TECHFRESH畢業分享會 - 葬送的通靈師:化系統與用戶雜訊成行動訊號
line_developers_tw
PRO
0
1.1k
Snowflakeと仲良くなる第一歩
coco_se
4
480
Disciplined Vibes: Scaling AI-Assisted Engineering
sheharyar
0
150
プロダクト開発から業務改善コンサルまで。事業全体へ「染み出す」ことで広がるエンジニアの可能性
ham0215
0
130
Chainlitで作るお手軽チャットUI
ynt0485
0
260
Featured
See All Featured
The World Runs on Bad Software
bkeepers
PRO
72
12k
SEOcharity - Dark patterns in SEO and UX: How to avoid them and build a more ethical web
sarafernandez
0
200
4 Signs Your Business is Dying
shpigford
187
22k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
35
2.5k
Marketing to machines
jonoalderson
1
5.5k
Design of three-dimensional binary manipulators for pick-and-place task avoiding obstacles (IECON2024)
konakalab
0
460
How to Build an AI Search Optimization Roadmap - Criteria and Steps to Take #SEOIRL
aleyda
1
2.1k
Measuring & Analyzing Core Web Vitals
bluesmoon
9
870
Speed Design
sergeychernyshev
33
1.8k
The B2B funnel & how to create a winning content strategy
katarinadahlin
PRO
1
390
How to train your dragon (web standard)
notwaldorf
97
6.7k
Jamie Indigo - Trashchat’s Guide to Black Boxes: Technical SEO Tactics for LLMs
techseoconnect
PRO
0
160
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