Upgrade to Pro — share decks privately, control downloads, hide ads and more …

20240908_共に歩む_Terraformと.pdf

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
Avatar for 木村直紀 木村直紀
January 07, 2025
6

 20240908_共に歩む_Terraformと.pdf

Avatar for 木村直紀

木村直紀

January 07, 2025
Tweet

Transcript

  1. 共に歩む、Terraformと ~ デ ィ レ ク ト リ 構 成

    改 善 と 予 期 せ ぬ コ ス ト へ の 対 策 ~
  2. 弊社がTerraformを使って数ヶ月後 devブランチ stgブランチ HCP Terraform GitHub prodブランチ Dev環境 Stg環境 Prod環境

    HCP Terraform HCP Terraform Push Engineer Marge Marge 環境は分けて、 コードを分けないよう にすれば実現可能
  3. # 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環境
  4. 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
  5. # 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環境の み作られるようにする。
  6. 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>" } } }
  7. 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 │ ├── │ ・・・ 『ディレクト構成の変更』 ここまでくれば、ディレクトリを環境によって分けなくても、 一つのディレクトリで管理することができる
  8. なぜ無用な設定がされていたか? 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を使うと設定が直感的に分かりにくいところがある…