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
20240908_共に歩む_Terraformと.pdf
Search
木村直紀
January 07, 2025
21
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
20240908_共に歩む_Terraformと.pdf
木村直紀
January 07, 2025
More Decks by 木村直紀
See All by 木村直紀
JAWS FESTA 2025でリリースしたほぼリアルタイム文字起こし/翻訳機能の構成について
naoki8408
1
1.3k
CodeCatalystでCDKのワークフローを簡単に作ろう!
naoki8408
0
23
20240615_LT_RAG機能について_.pdf
naoki8408
0
94
Featured
See All Featured
Lessons Learnt from Crawling 1000+ Websites
charlesmeaden
PRO
1
1.3k
Code Review Best Practice
trishagee
74
20k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
230
23k
Why Mistakes Are the Best Teachers: Turning Failure into a Pathway for Growth
auna
0
160
The Curse of the Amulet
leimatthew05
1
13k
Redefining SEO in the New Era of Traffic Generation
szymonslowik
1
340
How to Grow Your eCommerce with AI & Automation
katarinadahlin
PRO
1
210
Keith and Marios Guide to Fast Websites
keithpitt
413
23k
How To Speak Unicorn (iThemes Webinar)
marktimemedia
1
490
Between Models and Reality
mayunak
4
340
The Impact of AI in SEO - AI Overviews June 2024 Edition
aleyda
5
1.1k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
37
6.5k
Transcript
共に歩む、Terraformと ~ デ ィ レ ク ト リ 構 成
改 善 と 予 期 せ ぬ コ ス ト へ の 対 策 ~
名前:木村 直紀 趣味:ランニング、筋トレ 資格:AWS資格12冠、G検定、LPIC1 AWS Top Engineers エンジニア歴:3年目 所属:株式会社ベンジャミン 好きなAWSサービス:AWSサポート、ECS
自己紹介 出身:大阪府岸和田市
みなさまIaCの活用は していますか?
ここにいる方々は Jr. Champions、 もしくは、Top Engineers、 もしくは、Ambassadors
当然何かしらの IaCを使っていると思います
Terraform CloudFormation SAM CDK Ansible ServerlessFramework Chef Puppet AWSさん の会場でCDKの
発表じゃないの?
①Terraformディレクトリ構成の改善
TerraformなどのIaCツールを使う利点
Dev Stg Prod コピー コピー TerraformなどのIaCツールを使う利点
弊社がTerraformを使い始めた当初 devブランチ stgブランチ HCP Terraform GitHub prodブランチ Dev環境 Stg環境 Prod環境
HCP Terraform HCP Terraform Push Push Push Engineer ※旧 Terraform Cloud
Dev、Stg、Prod環境は 全く一緒というわけではなく、 環境によって値に差分が発生するところがあるので、 設定せざるおえない…
弊社がTerraformを使い始めた当初 devブランチ stgブランチ HCP Terraform GitHub prodブランチ Dev環境 Stg環境 Prod環境
HCP Terraform HCP Terraform Push Push Push Engineer
弊社がTerraformを使って数ヶ月後 devブランチ stgブランチ HCP Terraform GitHub prodブランチ Dev環境 Stg環境 Prod環境
HCP Terraform HCP Terraform Push Engineer Marge Marge 環境は分けて、 コードを分けないよう にすれば実現可能
変更点1 『環境変数で値を定義』
# VPC resource "aws_vpc" "VPC" { cidr_block = "${var.CIDR_FORMERHALF}.0.0/16" enable_dns_support
= true enable_dns_hostnames = true tags = { Env = "${var.ENV}", Service = "${var.SERVICE}", Name = "${var.ENV}-${var.SERVICE}-vpc" } } # Public Subnets resource "aws_subnet" "Subnet_Public_A" { availability_zone = "${var.REGION}a" cidr_block = "${var.CIDR_FORMERHALF}.0.0/24" vpc_id = aws_vpc.VPC.id map_public_ip_on_launch = true tags = { Env = "${var.ENV}", Service = "${var.SERVICE}", Name = "${var.ENV}-${var.SERVICE}-subnet-public-a" } } 名前や値が変わりそうなところは、 環境変数で定義することで、CICDパイプラインで、 環境変数を挿入するように設定してやれば、パイプ ラインによって、環境を分けることができる。 ※ここでCICDパイプラインと呼んでいるのはHCP Terraformのことである。 『環境変数で値を定義』 devブランチ HCP Terraform prodブランチ HCP Terraform Dev用の 環境変数を 挿入し、展開 Prod用の 環境変数を 挿入し、展開 Dev環境 Prod環境
変更点2 『三項演算子を使って場合分けする』
resource "aws_lb" "ALB" { name = "${var.ENV}-${var.SERVICE}-alb" internal = false
load_balancer_type = "application" ip_address_type = "ipv4" enable_cross_zone_load_balancing = true enable_deletion_protection = true security_groups = ["${aws_security_group.SecurityGroup_ALB.id}"] subnets = [ "${aws_subnet.Subnet_Public_A.id}", "${aws_subnet.Subnet_Public_C.id}", "${aws_subnet.Subnet_Public_D.id}" ] access_logs { enabled = var.ENV == "prod" ? true : false bucket = length(aws_s3_bucket.S3Bucket_Logs) > 0 ? aws_s3_bucket.S3Bucket_Logs[0].id : "" prefix = "elb" } tags = { Name = "${var.ENV}-${var.SERVICE}-alb", Env = "${var.ENV}", Service = "${var.SERVICE}" } } 環境によって変わるような値は三項演算子を使っ て、場合分けするようにする。 『三項演算子を使って場合分けする』 ALB 例)ALBのアクセスログはProd環境のみ適用するよ うにする。 Dev Prod S3 ALB S3
変更点3 『リソースのあるなしはcountを使う』
# S3 Bucket(Logs) resource "aws_s3_bucket" "S3Bucket_Logs" { count = var.ENV
== "prod" ? 1 : 0 bucket = "${var.ENV}-${var.SERVICE}-logs" tags = { Name = "${var.ENV}-${var.SERVICE}-logs" Env = "${var.ENV}", Service = "${var.SERVICE}" } } 環境によって不要になるリソースはcountを使って、 不要なら0にする。 『リソースのあるなしはcountを使う』 ALB Dev Prod S3 ALB S3 例)ALBのアクセスログのS3バケットはProd環境の み作られるようにする。
変更点4 『共通部分はモジュール化する』
bjm-terraform-app ├── common │ ├── iam_assume_role_policies │ │ └── template.json
│ ├── iam_policies │ │ └── EC2S3BasicPolicy.json │ ├── user_data │ │ └── ec2_user_data.sh │ ├── commont_network.tf │ ├── output.tf │ ├── provider.tf │ ├── variables.tf │ └── version.tf └── service ├── s3_bucket_policies │ ├── S3BucketPolicy_ELB_Accesslog.json │ ・・・ ├── iam_assume_role_policies │ ├── template_codecommit.json │ ・・・ ├── iam_policies │ ├── CodeBuildBasePolicy.json │ ・・・ ├── cicd.tf ├── app.tf ├── iam.tf ├── db.tf ├── remote_state.tf ├── strage.tf ├── locals.tf ├── provider.tf ├── variables.tf └── version.tf 『共通部分はモジュール化する』 案件によっては同じVPC内に、Dev、Stg、Prodの3環境を共存さ せるなど、環境によって分かれないリソースも存在するだろう。 そんな時は、共通リソースをcommonディレクトリにし、モジュー ルとして使うようにする。 output "vpc_id" { value = aws_vpc.VPC.id } output "subnet_public_a_id" { value = aws_subnet.Subnet_Public_A.id } output "subnet_public_c_id" { value = aws_subnet.Subnet_Public_C.id } output "subnet_public_d_id" { value = aws_subnet.Subnet_Public_D.id } ・・・ data "terraform_remote_state" "common" { backend = "remote" config = { organization = ”<HCP_Terraform_Org>" workspaces = { name = ”<HCP_Terraform_workspace_name>" } } }
変更点5 『ディレクト構成の変更』
bjm-terraform-app ├── common │ ├── iam_assume_role_policies │ │ └── template.json
│ ├── iam_policies │ │ └── EC2S3BasicPolicy.json │ ├── user_data │ │ └── ec2_user_data.sh │ ├── commont_network.tf │ ├── output.tf │ ├── provider.tf │ ├── variables.tf │ └── version.tf └── service ├── s3_bucket_policies │ ├── S3BucketPolicy_ELB_Accesslog.json │ ・・・ ├── iam_assume_role_policies │ ├── template_codecommit.json │ ・・・ ├── iam_policies │ ├── CodeBuildBasePolicy.json │ ・・・ ├── cicd.tf ├── app.tf ├── iam.tf ├── db.tf ├── remote_state.tf ├── strage.tf ├── locals.tf ├── provider.tf ├── variables.tf └── version.tf bjm-terraform-app ├── dev │ ├── common │ │ ├── iam_assume_role_policies │ │ │ └── template.json │ │ ├── iam_policies │ │ │ └── EC2S3BasicPolicy.json │ │ ├── user_data │ │ │ └── ec2_user_data.sh │ │ ├── commont_network.tf │ │ ├── output.tf │ │ ├── provider.tf │ │ ├── variables.tf │ │ └── version.tf │ └── service │ ├── s3_bucket_policies │ │ ├── S3BucketPolicy_ELB_Accesslog.json │ │ ・・・ │ ├── iam_assume_role_policies │ │ ├── template_codecommit.json │ │ ・・・ │ ├── iam_policies │ │ ├── CodeBuildBasePolicy.json │ │ ・・・ │ ├── cicd.tf │ ├── app.tf │ ├── iam.tf │ ├── db.tf │ ├── remote_state.tf │ ├── strage.tf │ ├── locals.tf │ ├── provider.tf │ ├── variables.tf │ └── version.tf │ ├── stg │ ├── │ ・・・ │ ├── prod │ ├── │ ・・・ 『ディレクト構成の変更』 ここまでくれば、ディレクトリを環境によって分けなくても、 一つのディレクトリで管理することができる
弊社がTerraformを使って数ヶ月後 devブランチ stgブランチ HCP Terraform GitHub prodブランチ Dev環境 Stg環境 Prod環境
HCP Terraform HCP Terraform Push Engineer Marge Marge
②予期せぬコストへの対策
皆様はCloudFrontのこの設定を知っていますか? こちらは『レガシークライアントサポート』と言い、独自 のSSLを設定する場合に選択する項目になります。 $600/月ほどかかるので、 余程要件に入ってないと選択しない項目になります。 すぐに気づけたので問題なかったですが、 一時的に、この項目がONになっていました…
なぜ無用な設定がされていたか? resource “aws_cloudfront_distribution” "CloudFrontDistribution" { enabled = true price_class =
"PriceClass_All" http_version = "http2" is_ipv6_enabled = true aliases = ["${var.CLOUDFRONT_CUSTOM_DOMAIN_NAME}"] viewer_certificate { cloudfront_default_certificate = false acm_certificate_arn = "arn:aws:acm:us-east- 1:${var.AWS_ACCOUNT_ID}:certificate/${var.CLOUDFRONT_CERTIFICATE_ID}" minimum_protocol_version = "TLSv1.2_2021" ssl_support_method = ”vip" } ・・・ IaCを使うと設定が直感的に分かりにくいところがある…
無用なコストを発生させないための対策 『Infracostを活用して予期せぬコストの対策』 Infracostを活用すると、左のようにコードを記載し たタイミングで、現在のコードを展開するとどれだ けコストがかかるか表示してくれる。 VS Codeの拡張機能から使えるので、利用も手軽 ※正し、従量課金のリソースに関してはコストが表 示されないので、注意が必要。
まとめ • 各ブランチに直接pushしないようにコードを工夫しよう • Infracostを使って、余分なコストを発生させないようにしよう