Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Speaker Deck
PRO
Sign in
Sign up for free
layerx-invoice-practical-devops-20211029
shnjtk
October 30, 2021
5
10k
layerx-invoice-practical-devops-20211029
shnjtk
October 30, 2021
Tweet
Share
More Decks by shnjtk
See All by shnjtk
layerx-invoice-practical-aws-architecture
shnjtk
1
1.7k
How to develop LayerX INVOICE efficiently
shnjtk
3
2.7k
Featured
See All Featured
Stop Working from a Prison Cell
hatefulcrawdad
262
17k
Keith and Marios Guide to Fast Websites
keithpitt
404
21k
The Straight Up "How To Draw Better" Workshop
denniskardys
225
130k
Build The Right Thing And Hit Your Dates
maggiecrowley
19
1.2k
Web Components: a chance to create the future
zenorocha
303
40k
Gamification - CAS2011
davidbonilla
75
3.9k
GitHub's CSS Performance
jonrohan
1020
420k
From Idea to $5000 a Month in 5 Months
shpigford
373
44k
Rebuilding a faster, lazier Slack
samanthasiow
62
7.3k
GraphQLとの向き合い方2022年版
quramy
16
8.4k
YesSQL, Process and Tooling at Scale
rocio
157
12k
Designing on Purpose - Digital PM Summit 2013
jponch
106
5.7k
Transcript
© LayerX Inc. 実践 DevOps チーム全員でインフラを管理する @shnjtk 2021/10/29 JAWS-UG コンテナ支部
#20
© LayerX Inc. 自己紹介 高江 信次 (Shinji Takae) 株式会社LayerX CTO室
リードエンジニア LayerX インボイスの開発メンバーとして主にインフラを担当 コーポレートエンジニア的な業務も一部兼任 好きなAWSサービス 2 AWS Fargate Amazon Aurora Lambda
© LayerX Inc. 今日話すこと スピードを落とさず効率的にサービスを開発するために LayerX インボイスの開発チームが一体となって取り組んでいる インフラの管理方法 3
© LayerX Inc. アジェンダ • 開発チーム構成と普段の開発の様子 • チームとして達成したいこと • 実践していること
• まとめ 4
© LayerX Inc. 開発チーム構成 5 LayerX インボイス LayerX ワークフロー インフラ開発・デザイン・
QA AI-OCR
© LayerX Inc. 普段の開発の様子 • インフラの全体的な設計や開発など大掛かりな作業は基本的に インフラ担当が行う • 軽微な変更はアプリ担当が自分で対応することもある •
IaC化する前に、テスト的に管理画面から手動でリソースを作ることもある • 手動で作って不要になったリソースの削除やIaC化はインフラ担当が行う • 結果的に、チーム全員が自然とインフラに関わっている 6
© LayerX Inc. 達成したいこと • インフラ開発がボトルネックになって開発スピードが落ちるのを防ぐ • 最終的に必要となるリソースはIaCで管理する 7
© LayerX Inc. 実践していること • IaCリポジトリのディレクトリ構成とファイルの命名規則 • タグ付けによるIaCリポジトリの明確化 • 再利用性を意識したリソース定義
• CI/CDの自動化とtfstateのバージョン管理 • plan実行時の差分を減らす工夫 • ツールの使い分け 8
© LayerX Inc. IaCリポジトリのディレクトリ構成 9 invoice-infra ├── aws_cloudwatch_logs.tf ├── aws_ecs.tf
├── aws_iam_ecs.tf ├── aws_iam_lambda.tf ├── aws_kms.tf ├── aws_rds.tf ├── aws_route53.tf ├── aws_s3.tf ├── aws_secrets.tf ├── buildspec.yml ├── data.tf ├── datadog_dashboard_ecs.tf ├── datadog_integration.tf ├── datadog_monitor_ecs.tf ├── datadog_monitor_rds.tf ├── datadog_synthetics_test.tf ├── env │ ├── dev.tfvars │ ├── prd.tfvars │ └── stg.tfvars ├── locals.tf ├── provider.tf └── variables.tf (一部抜粋) • リポジトリ直下に.tfファイルをフラットに配置 • 環境変数は.tfvarsファイルで定義して envディレクトリに配置 ◦ terraformコマンド実行時に引数で指定 • プロジェクト固有の定数はlocals.tfで定義
© LayerX Inc. Terraformファイルの命名規則 • (provider)_(resource)_(target).tf ◦ 例: aws_iam_ecs.tf、aws_iam_lambda.tf •
targetがなかったり、自明な場合は省略 ◦ 例: aws_rds.tf、aws_kms.tf • 目的 ◦ インフラのコードに普段はあまり関わらないメンバーであっても、コードを変更する際にどのファイル を編集すればいいか一目で分かる • 上記はあくまで一例 ◦ チーム内で一貫性があって、変更したい目的のファイルをすぐに特定できればよい 10
© LayerX Inc. タグ付けによるIaCリポジトリの明確化 • default_tagsを利用して、各リソースを管理してい るIaCリポジトリがどれであるかを示すタグを付与 する • 目的
◦ アプリ担当がリソースに変更を加えたい場合に IaCリポジトリがすぐに分かる ◦ これが付与されていないものは手動で作ったテスト用リ ソースであると判断できる → リソース棚卸し時の削除対象 11 locals { service_id = "invoice" managed_by = "invoice-infra" } provider "aws" { region = “ap-northeast-1” default_tags { tags = { service_id = local.service_id managed_by = local.managed_by env = var.env } } } locals.tf provider.tf
© LayerX Inc. 再利用性を意識したリソース定義 • アプリ開発メンバーがインフラに変更 を加えるケースの例 ◦ S3 bucketを追加したい
◦ IAM policyを変更したい ◦ DynamoDB tableを追加したい • なるべくコピペしやすいようにlocals やvarを使って共通部分は そのまま使えるようにする • 暗号化設定や非公開設定など、守っ てほしい部分も漏れなく カバーされるようにリソース定義を隣 接させておく 12 resource "aws_s3_bucket" "csv_files" { bucket = "${local.service_id}-${var.env}-csv-files" acl = "private" versioning { enabled = true } server_side_encryption_configuration { rule { apply_server_side_encryption_by_default { kms_master_key_id = aws_kms_key.main.arn sse_algorithm = "aws:kms" } } } } resource "aws_s3_bucket_public_access_block" "csv_files" { bucket = aws_s3_bucket.csv_files.id block_public_acls = true block_public_policy = true ignore_public_acls = true restrict_public_buckets = true }
© LayerX Inc. CI/CDの自動化とtfstateのバージョン管理 • plan/applyの実行は自動化する ◦ planやapplyの結果をチームで共有することにより レビューしやすくなる •
tfstateファイルは必ずリモートバックエンドで保管しバージョ ン管理を有効にする ◦ バージョン管理することで、もし何かあった場合でも tfstateをロール バックすることができる ◦ 「何かあってもすぐに元に戻せる」という安心感があることで 失敗を恐れずにインフラを変更できる 13 PR plan apply tfstate
© LayerX Inc. plan実行時に差分を減らす工夫 14 例: data sourceが参照しているリソースを変更した場合 resource "aws_s3_bucket"
"csv_files" { bucket = "csv-files" tags = { foo = “bar” # -> “baz” に変更すると... } } data “aws_iam_policy_document” “csv_reader” { statement { effect = “Allow” actions = [“s3:GetObject”] resources = [“${aws_s3_bucket.csv_files.arn}/*”] } } resource “aws_iam_policy” “csv_reader” { name = “csv-reader” policy = data.aws_iam_policy_document.csv_reader.json } # aws_s3_bucket.sample will be updated in-place ~ resource "aws_s3_bucket" "csv_files" { ~ tags = { ~ "foo" = "bar" -> "baz" } # (config refers to values not yet known) <= data "aws_iam_policy_document" "csv_reader" { ~ id = "232721XXXX" -> (known after apply) ~ json = jsonencode( { - Statement = [ - { - Action = "s3:GetObject" - Effect = "Allow" - Resource = "arn:aws:s3:::csv-files/*" - Sid = "" }, ] - Version = "2012-10-17" } ) -> (known after apply) - version = "2012-10-17" -> null } # aws_iam_policy.sample will be updated in-place ~ resource "aws_iam_policy" "csv_reader" { id = "arn:aws:iam::XXX:policy/csv-reader" name = "csv-reader" ~ policy = jsonencode( { - Statement = [ - { - Action = "s3:GetObject" - Effect = "Allow" - Resource = "arn:aws:s3:::csv-files/*" - Sid = "" }, ] - Version = "2012-10-17" } ) -> (known after apply) } Plan: 0 to add, 2 to change , 0 to destroy.
© LayerX Inc. plan実行時に差分を減らす工夫 15 resource "aws_s3_bucket" "csv_files" { bucket
= "csv-files" tags = { foo = “bar” # -> “baz” に変更すると... } } resource "aws_iam_policy" "csv_reader" { name = "csv-reader" policy = jsonencode({ Version = "2012-10-17" Statement = [{ Effect = "Allow" Action = ["s3:GetObject"] Resource = ["${aws_s3_bucket.csv_files.arn}/*"] }] }) } Terraform will perform the following actions: # aws_s3_bucket.sample will be updated in-place ~ resource "aws_s3_bucket" "csv_files" { id = “csv-files" ~ tags = { ~ "foo" = "bar" -> "baz" } ~ tags_all = { ~ "foo" = "bar" -> "baz" } # (9 unchanged attributes hidden) # (1 unchanged block hidden) } Plan: 0 to add, 1 to change, 0 to destroy. 対策: jsonencodeでインライン化する
© LayerX Inc. ツールの使い分け • 基本的にはTerraformを使用してリソースを管理する • Lambda関数はケース・バイ・ケースで使い分ける ◦ jsファイル1つで済む程度の軽いものであればTerraform
◦ パッケージインストールや複雑なビルドが必要なものは AWS CDK • AWS CDKを使う場合は対象をLambda関数だけにする ◦ 厳密には、Lambda関数とそれをデプロイするためのCloudFormation stack ◦ Lambda関数に付与するIAM role/policyや、その他必要なリソースはTerraformで管理 • 目的 ◦ Lambda関数はアプリ担当が変更を加えることが多く、デプロイの際に関数以外のことを意識しなくても 済むように ◦ リソースはそれぞれ関連(参照)している場合が多く、生成や変更の順序に依存性があったりするので、 そういった点はTerraformで解決する 16
© LayerX Inc. まとめ • 誰でもインフラ開発ができるように、一貫性のあるルールを設けて シンプルなファイル構成、再利用性の高いリソース定義にしよう • タグを活用してリソースの管理状況を可視化しよう •
CI/CD環境を構築して処理を自動化し、チームメンバーがレビューできる ようにしよう • plan実行時の差分を減らすためにコードをリファクタしよう • ツールは1つに絞らず適材低所で採用しよう 17 開発スピードを落とさず、IaCもきちんと行うために: