Slide 1

Slide 1 text

Terraform あれやこれ 2024 年 4 月 19 日 JAWS-UG朝会 #56

Slide 2

Slide 2 text

2 目次 • はじめに • Terraform おさらい • Terraform リソース名? • Terraform モジュールの話 • Terraform スタイルガイド • その他 Terraform 初級者向け

Slide 3

Slide 3 text

3 目次 • はじめに • Terraform おさらい • Terraform リソース名? • Terraform モジュールの話 • Terraform スタイルガイド • その他

Slide 4

Slide 4 text

4 はじめに

Slide 5

Slide 5 text

5 はじめに • 普段 AWS リソースを作成する際、 一番よく利用する IaC ツールは何ですか? 1. CloudFormation 2. Terraform 3. CDK 4. SAM 5. Serverless Framework 6. Pulumi 7. その他

Slide 6

Slide 6 text

6 はじめに • JAWS DAYS 2024 - LEAP BEYOND • ぼくのかんがえたさいきょうのAWSへのリソースデプロイ • https://jawsdays2024.jaws-ug.jp/sessions/timetable/C-1/ • https://dev.classmethod.jp/articles/jaws-days-2024-boku-saikyo-aws-deploy/

Slide 7

Slide 7 text

7 目次 • はじめに • Terraform おさらい • Terraform リソース名? • Terraform モジュールの話 • Terraform スタイルガイド • その他

Slide 8

Slide 8 text

8 Terraform おさらい

Slide 9

Slide 9 text

9 Terraform おさらい • HashiCorp 社が提供する IaC ツール • 様々なプロバイダーのリソースを HCL という言語で書かれた ソースコードで管理でき、バージョン管理、再利用、共有が可能 • プロバイダーの例: • AWS、Azure、Google Cloud、Kubernetes、Alibaba Cloud、 Olacle Cloud、Docker、Cloudflare、akamai etc…

Slide 10

Slide 10 text

10 Terraform おさらい • AWS リソースを Terraform でデプロイする場合… • Terraform を実行するマシンに Terraform をインストールする必要がある • Terraform は AWS CLI の権限を使用して AWS に API を 叩きに行くので AWS CLI のセットアップが必要 AWS Cloud AWS CLI ①手元の開発端末にインストールして ②デプロイ ECS AWS Cloud ECS AWS Cloud9 AWS CLI ②AWS 上のコンピュートサービスにインストールして ②デプロイ

Slide 11

Slide 11 text

11 Terraform おさらい • 環境が整ったら、ソースコードを書く • Terraform のソースコードは .tf という拡張子で保存する ################################################## # Terraform settings ################################################## terraform { # Terraform バージョンの指定 required_version = "~> 1.4" # AWS プロバイダーのバージョン指定 required_providers { aws = { source = "hashicorp/aws" version = "~> 5.01" } } # tfstate ファイルを S3 に配置する(配置先の S3 は事前に作成しておく) backend s3 { bucket = "tfstate-emikitani" region = "ap-northeast-1" key = "tf-test-20240402.tfstate" } } ################################################## # Provider settings ################################################## # AWS プロバイダーの定義 provider aws { region = "ap-northeast-1" } ################################################## # VPC ################################################## # VPC resource "aws_vpc" "vpc" { cidr_block = "10.0.0.0/16" enable_dns_support = true enable_dns_hostnames = true tags = { Name = "vpc" } } # Internet Gateway resource "aws_internet_gateway" "igw" { vpc_id = aws_vpc.vpc.id tags = { Name = "igw" } } main.tf という名前で保存

Slide 12

Slide 12 text

12 Terraform おさらい • 環境が整ったら、ソースコードを書く ################################################## # Terraform settings ################################################## terraform { # Terraform バージョンの指定 required_version = "~> 1.4" # AWS プロバイダーのバージョン指定 required_providers { aws = { source = "hashicorp/aws" version = "~> 5.01" } } # tfstate ファイルを S3 に配置する(配置先の S3 は事前に作成しておく) backend s3 { bucket = "tfstate-emikitani" region = "ap-northeast-1" key = "tf-test-20240402.tfstate" } } ################################################## # Provider settings ################################################## # AWS プロバイダーの定義 provider aws { region = "ap-northeast-1" } ################################################## # VPC ################################################## # VPC resource "aws_vpc" "vpc" { cidr_block = "10.0.0.0/16" enable_dns_support = true enable_dns_hostnames = true tags = { Name = "vpc" } } # Internet Gateway resource "aws_internet_gateway" "igw" { vpc_id = aws_vpc.vpc.id tags = { Name = "igw" } } Terraform の設定 プロバイダーの設定 リソースの作成

Slide 13

Slide 13 text

13 Terraform おさらい • Terraform の設定 • Terraform は一番最初に Terraform ブロックを読み込む • Terraform バージョンの指定 (required_version) • Terraform のどのバージョン が必要かを指定 • プロバイダーの指定 (required_providers ) • AWS などのプロバイダーの ソースとバージョンを指定 ################################################## # Terraform settings ################################################## terraform { # Terraform バージョンの指定 required_version = "~> 1.4" # AWS プロバイダーのバージョン指定 required_providers { aws = { source = "hashicorp/aws" version = "~> 5.01" } } # tfstate ファイルを S3 に配置する(配置先の S3 は事前に作成しておく) backend s3 { bucket = "tfstate-emikitani" region = "ap-northeast-1" key = "tf-test-20240402.tfstate" } } https://developer.hashicorp.com/terraform/language/settings https://developer.hashicorp.com/terraform/language/expressions/version-constraints {} で囲まれた部分を 「ブロック」と呼ぶ Terraform にも プロバイダーにも バージョンがある

Slide 14

Slide 14 text

14 Terraform おさらい • Terraform の設定 • バックエンドの設定 • Terraform は状態ファイル (tfstate ファイル)で インフラの状態を追跡する • tfstate ファイルをどこに保存 するか指定する • bucket = S3 バケットの名前 • region = S3 バケットが配置 されているリージョン • key = S3 バケット内の状態 ファイルの名前と場所 ################################################## # Terraform settings ################################################## terraform { # Terraform バージョンの指定 required_version = "~> 1.4" # AWS プロバイダーのバージョン指定 required_providers { aws = { source = "hashicorp/aws" version = "~> 5.01" } } # tfstate ファイルを S3 に配置する(配置先の S3 は事前に作成しておく) backend s3 { bucket = "tfstate-emikitani" region = "ap-northeast-1" key = "tf-test-20240402.tfstate" } }

Slide 15

Slide 15 text

15 Terraform おさらい • プロバイダーの設定 • リージョンの指定(region) • 他、ここでバージョンを指定するこ とも AWS CLI のプロファイル (profile)を記述することもできる ################################################## # Provider settings ################################################## # AWS プロバイダーの定義 provider aws { region = "ap-northeast-1" } https://registry.terraform.io/providers/hashicorp/aws/latest/docs

Slide 16

Slide 16 text

16 Terraform おさらい • リソースの作成 • 実際のリソース作成部分 • リソース作成時の基本的な構文 ################################################## # VPC ################################################## # VPC resource "aws_vpc" "vpc" { cidr_block = "10.0.0.0/16" enable_dns_support = true enable_dns_hostnames = true tags = { Name = "vpc" } } # Internet Gateway resource "aws_internet_gateway" "igw" { vpc_id = aws_vpc.vpc.id tags = { Name = "igw" } } https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/internet_gateway resource "リソースの種類" "リソース名" { 設定項目1 = 値1 設定項目2 = 値2 設定項目3 = 値3 }

Slide 17

Slide 17 text

17 Terraform おさらい • リソースの作成 • 実際のリソース作成部分 • リソース作成時の基本的な構文 ################################################## # VPC ################################################## # VPC resource "aws_vpc" "vpc" { cidr_block = "10.0.0.0/16" enable_dns_support = true enable_dns_hostnames = true tags = { Name = "vpc" } } # Internet Gateway resource "aws_internet_gateway" "igw" { vpc_id = aws_vpc.vpc.id tags = { Name = "igw" } } https://developer.hashicorp.com/terraform/language/expressions/references resource "リソースの種類" "リソース名" { 設定項目1 = 値1 設定項目2 = 値2 設定項目3 = 値3 } . の形式で リソースを指定する

Slide 18

Slide 18 text

18 Terraform おさらい • ソースコードができたら、terraform コマンドで リソースをデプロイする • terraform init 環境準備 • ワークスペースの初期化や必要なプラグインのダウンロード • terraform plan 何ができるか確認 • ソースコードに基づいてどのようなリソースが作成、更新、削除されるか表示する • terraform apply リソース作成 • terraform planで提案されたリソースを作成、更新、削除する • コマンド実行時には変更内容が再度確認され、ユーザが変更を承認する必要がある • terraform destroy リソース削除 • Terraformによって管理されているすべてのリソースを削除する

Slide 19

Slide 19 text

19 目次 • はじめに • Terraform おさらい • Terraform リソース名? • Terraform モジュールの話 • Terraform スタイルガイド • その他

Slide 20

Slide 20 text

20 Terraform リソース名?

Slide 21

Slide 21 text

21 Terraform リソース名? • リソースの作成 • 実際のリソース作成部分 • リソース作成時の基本的な構文 https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/internet_gateway resource "リソースの種類" "リソース名" { 設定項目1 = 値1 設定項目2 = 値2 設定項目3 = 値3 } ################################################## # VPC ################################################## # VPC resource "aws_vpc" "vpc" { cidr_block = "10.0.0.0/16" enable_dns_support = true enable_dns_hostnames = true tags = { Name = "vpc" } } # Internet Gateway resource "aws_internet_gateway" "igw" { vpc_id = aws_vpc.vpc.id tags = { Name = "igw" } } これ何?

Slide 22

Slide 22 text

22 Terraform リソース名? • “main” だったり ”this” だったりする resource "aws_vpc" "main" { cidr_block = "10.0.0.0/16" # VPCのCIDRブロック tags = { Name = "main-vpc" } } resource "aws_internet_gateway" “this" { vpc_id = aws_vpc.main.id tags = { Name = "igw" } }

Slide 23

Slide 23 text

23 Terraform リソース名? • CloudFormationで言うと ここの「論理 ID(リソース の名前)」みたいなもの • ※イメージです Resources: TestVPC: Type: AWS::EC2::VPC Properties: CidrBlock: 10.0.0.0/16 Tags: - Key: Name Value: TEST-VPC

Slide 24

Slide 24 text

24 Terraform リソース名? • 「Terraform Best Practices」 の 「Naming conventions」に記載 がある • https://www.terraform-best-practices.com/naming • リソース名の主な目的 • 同じタイプの複数のリソースを 一意に区別できるようにする • 単一のリソースである場合、 もしくは適切な名称が無い場合 は this を使う resource "aws_vpc" “this" { # … } resource "aws_instance" "web" { # … } resource "aws_instance" “app" { # … } resource "aws_instance" “bastion" { # … } VPC は一つしかないので this EC2 は複数あるので用途などに 合わせて適切な名称を付ける

Slide 25

Slide 25 text

25 Terraform リソース名? • リソース名でリソースタイプを繰り返すべきではない resource "aws_route_table" "public" { # … } resource "aws_route_table" "public_route_table" { # … }

Slide 26

Slide 26 text

26 Terraform リソース名? • つまり、これはあまり良く なかったってことです • this などにした方が良い ################################################## # VPC ################################################## # VPC resource "aws_vpc" "vpc" { cidr_block = "10.0.0.0/16" enable_dns_support = true enable_dns_hostnames = true tags = { Name = "vpc" } } # Internet Gateway resource "aws_internet_gateway" "igw" { vpc_id = aws_vpc.vpc.id tags = { Name = "igw" } }

Slide 27

Slide 27 text

27 目次 • はじめに • Terraform おさらい • Terraform リソース名? • Terraform モジュールの話 • Terraform スタイルガイド • その他

Slide 28

Slide 28 text

28 Terraform モジュールの話

Slide 29

Slide 29 text

29 Terraform モジュールの話 main.tf よし、完璧だ

Slide 30

Slide 30 text

30 Terraform モジュールの話 main.tf リソース名の頭に システム略称を つけたいなぁ

Slide 31

Slide 31 text

31 Terraform モジュールの話 main.tf リソース名の頭に システム略称を つけたいなぁ VPC の tag を編集 Public Subnet の tag を編集 Private Subnet の tag を編集 Security Group の tag を編集 EC2 1 台目の tag を編集 EC2 2 台目の tag を編集 EC2 3 台目の tag を編集 ALB の tag を編集

Slide 32

Slide 32 text

32 Terraform モジュールの話 main.tf リソース名の頭に システム略称を つけたいなぁ VPC の tag を編集 Public Subnet の tag を編集 Private Subnet の tag を編集 Security Group の tag を編集 EC2 1 台目の tag を編集 EC2 2 台目の tag を編集 EC2 3 台目の tag を編集 ALB の tag を編集 いちいち全部修正するのは面倒くさい ミスが起きる可能性

Slide 33

Slide 33 text

33 Terraform モジュールの話 main.tf variables.tf 変数を管理する .tf ファイルに分ける

Slide 34

Slide 34 text

34 Terraform モジュールの話 main.tf variables.tf 変数を管理する .tf ファイルに分ける ############################## # VPC ############################## resource "aws_vpc" “this" { cidr_block = "10.0.0.0/16" enable_dns_support = true enable_dns_hostnames = true tags = { Name = "${var.prefix}-vpc" } } variable "prefix" { type = string description = "リソース名のプリフィックス“ default = “emiki" }

Slide 35

Slide 35 text

35 Terraform モジュールの話 main.tf 開発環境も作ろう main.tf

Slide 36

Slide 36 text

36 Terraform モジュールの話 main.tf XX 環境も作ろう main.tf main.tf main.tf main.tf

Slide 37

Slide 37 text

37 Terraform モジュールの話 main.tf あ、リソースの 構成を変えたい main.tf main.tf main.tf main.tf

Slide 38

Slide 38 text

38 Terraform モジュールの話 main.tf 修正 main.tf main.tf main.tf main.tf 修正 修正 修正 修正

Slide 39

Slide 39 text

39 Terraform モジュールの話 main.tf 修正 main.tf main.tf main.tf main.tf 修正 修正 修正 修正 いちいち全部修正するのは面倒くさい ミスが起きる可能性

Slide 40

Slide 40 text

40 Terraform モジュールの話 root main.tf envs dev prd modules vpc ec2 variables.tf main.tf main.tf output.tf main.tf variables.tf output.tf

Slide 41

Slide 41 text

41 Terraform モジュールの話 root main.tf envs dev prd modules vpc ec2 variables.tf main.tf main.tf output.tf main.tf variables.tf output.tf ルートモジュール 子モジュール

Slide 42

Slide 42 text

42 Terraform モジュールの話 root main.tf envs dev prd modules vpc ec2 variables.tf main.tf main.tf output.tf main.tf variables.tf output.tf VPC というモジュールを 一つ作成すれば 複数の環境に展開できる

Slide 43

Slide 43 text

43 Terraform モジュールの話 root main.tf envs dev prd modules vpc ec2 variables.tf main.tf main.tf output.tf main.tf variables.tf output.tf EC2 というモジュールを 一つ作成すれば 複数の環境に展開できる

Slide 44

Slide 44 text

44 Terraform モジュールの話 • output.tf やモジュールの呼び出しはこちらを参照ください!!! • [登壇レポート]「やさしいTerraform Module入門」というタイトルで登壇 しました • https://dev.classmethod.jp/articles/terraform_speaker_report_jaws ug_tokyo/

Slide 45

Slide 45 text

45 目次 • はじめに • Terraform おさらい • Terraform リソース名? • Terraform モジュールの話 • Terraform スタイルガイド • その他

Slide 46

Slide 46 text

46 Terraform スタイルガイド

Slide 47

Slide 47 text

47 Terraform スタイルガイド • 2024/3/30 Terraform 公式ドキュメントとしてスタイルガイドが 公開された • https://developer.hashicorp.com/terraform/language/style • これまで存在していた Terraform のスタイルに関するドキュメント • Terraform を使用するためのベスト プラクティス | Google Cloud • https://cloud.google.com/docs/terraform/best-practices-for-terraform?hl=ja • Google Cloud が提供 • Terraform Best Practices • https://www.terraform-best-practices.com/ • ノルウェーのエンジニアの方が主導で提供しているコミュニティのドキュメント

Slide 48

Slide 48 text

48 Terraform スタイルガイド • コメントには # を使用 • 複数の単語を区切る際はアンダースコアを使用 • 例:○container_envs、×container-envs • リソースタイプとリソース名は二重引用符で囲む • 例:resource “aws_wafv2_ip_set” “primary_general_allow” { #... } • すべての variable、 output に description を含める • variables や local の過度の使用は避ける • count や for_each は控えめに利用する • etc…

Slide 49

Slide 49 text

49 目次 • はじめに • Terraform おさらい • Terraform リソース名? • Terraform モジュールの話 • Terraform スタイルガイド • その他

Slide 50

Slide 50 text

50 その他

Slide 51

Slide 51 text

51 その他 • モジュールの名前を間違えた • moved ブロックを使うとモジュールの名前を置き換えることができる • movedブロックを使ってリファクタリングしてみた • https://dev.classmethod.jp/articles/terraform-moved-block-resource- refactoring/ • MFA 認証を使ってスイッチロールして Terraform を実行する • MFA認証を使ったAssumeRoleでTerraformをシンプルに実行する(aws configure export-credentials) • https://dev.classmethod.jp/articles/terraform-mfa-assumerole-export-credentials/ • map 型、list 型、object 型…

Slide 52

Slide 52 text

52 奥が深い

Slide 53

Slide 53 text

53 ありがとうございました

Slide 54

Slide 54 text

54 参考 • Terraform by HashiCorp • https://www.terraform.io/ • What is Terraform | Terraform • https://developer.hashicorp.com/terraform/intro • Browse Providers | Terraform Registry • https://registry.terraform.io/browse/providers • Cloud9 上で Terraform の実行環境を作る~Amazon Linux 2023 版~ • https://dev.classmethod.jp/articles/cloud9-terraform-al2023/