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
12k
layerx-invoice-practical-devops-20211029
shnjtk
October 30, 2021
Tweet
Share
More Decks by shnjtk
See All by shnjtk
layerx-bakuraku-how-to-achieve-agility-and-security
shnjtk
1
250
layerx-invoice-practical-aws-architecture
shnjtk
1
1.9k
How to develop LayerX INVOICE efficiently
shnjtk
3
2.9k
Featured
See All Featured
4 Signs Your Business is Dying
shpigford
171
20k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
24
4.6k
Creatively Recalculating Your Daily Design Routine
revolveconf
207
11k
Designing on Purpose - Digital PM Summit 2013
jponch
108
5.9k
Typedesign – Prime Four
hannesfritz
34
1.5k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
236
1.1M
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
13
1.1k
Become a Pro
speakerdeck
PRO
6
3.2k
Thoughts on Productivity
jonyablonski
49
2.7k
Building a Scalable Design System with Sketch
lauravandoore
451
31k
From Idea to $5000 a Month in 5 Months
shpigford
374
44k
In The Pink: A Labor of Love
frogandcode
132
21k
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もきちんと行うために: