Terraform を運用するについて考える ~第1回 Terraformを管理する~
こんにちは、クラウドリードチームのフクナガです。
みなさん「Terraform」使ってますか?
クラウド利用の拡大に伴い、多くの会社でIaC(Infrastructure as Code)を取り入れようと様々な取り組みをされているかと思います。
私も、その中の1人として約3年ほどTerraformを利用した環境構築や運用に携わってきました。
私自身の経験をもとに、複数回にわたってTerraform運用面のノウハウをご紹介したいと思います。
第1回の本記事では、「Terraformを管理する」というテーマでお話ししたいと思います。
前提
対象環境
本記事では、AWSを利用し環境を構築することを前提としております。
想定している読者
本記事は、Terraform入門記事よりも「運用」に特化しているため、丁寧な文法解説などは記載されていません。
初学者の方は、実際にハンズオン記事などでTerraformを触ってみてからご覧いただくとより理解につながるかと思います。
今回の記事のスコープ
- Terraform開発/運用において管理すべきものを把握する
Terraformを管理するとは?
Terraformは、開発/運用をするにあたっていくつか管理しないといけないものがあります。
本記事では、管理する対象と対象ごとの管理方法をご紹介したいと思います。
1. 構築対象を管理する
providers.tf
Terraformで構築する対象のプロバイダー(AWS,GCPなど)や構築対象のリージョン、利用するTerraformのバージョンなどを定義するファイルになります。
Terraformが対応しているプロバイダーの一覧はこちらで参照ができます。
https://registry.terraform.io/browse/providers
「どのAWSアカウントでリソースを構築するのか」については利用するIAMユーザのアクセスキーを用いることで指定が可能です。(IAMロールを用いての実行なども可能)
※ファイル名は必ずしも「providers.tf」である必要はありません。
以下の内容で作成したファイルを他Terraformソースファイルと同一のディレクトリに配置しTerraformを実行することで、指定したプロバイダー、リージョンへのリソース構築が可能になります。
ファイル名:providers.tf
terraform { required_version ">= [利用するバージョンを記載]" } # プロバイダーとしてAWSを指定 provider "aws" { region = "[リージョン名]" }
複数リージョンでの構築を実施する場合は、以下の手順で実施できます。
(1) providers.tfに構築対象リージョンごとにproviderを定義する
ファイル名:providers.tf
terraform { required_version ">= [利用するバージョンを記載]" } # デフォルトで構築するリージョンにはaliasを定義しない provider "aws" { region = "[リージョン名]" } # 特定のリソースで利用するリージョンにはaliasを定義する provider "aws" { region = "us-east-1" alias = "virginia" }
(2) 構築対象リソースの中にproviderを定義する
例:EC2をバージニア北部リージョンに構築する場合
resource "aws_instance" "default" { provider = aws.virginia instance_type = "t3.micro" vpc_security_group_ids = ["セキュリティグループID"] subnet_id = サブネットのID root_block_device { volume_type = "gp3" volume_size = 8 encrypted = false } tags = { Name = "sample-ec2-server" } }
2. Terraformの状態を管理する
(1) tfstateファイル
Terraformでは、「tfstate」というファイルを用いて「実環境はどういう状態になっているのか?」「現状のTerraformコードと実環境でどういう差分があるのか?」といった管理をしています。
複数人で開発を実施する際は、このtfstateファイルを共通で持つ必要があります。
AWSでは、S3を利用することで共通のtfstateファイルを用いたTerraform開発が実現できます。
[手順]
1. tfstate保管用S3バケットを作成
tfstateを管理するためのS3バケットは「CloudFormation」にて作成します。
Terraformを利用するための仕組みは「CloudFormation」、その他のAWSリソースを「Terraform」で構築することで、AWSリソース全てをコード管理することが可能になります。
CloudFormationを利用したリソース作成の経験がない方は以下記事を参照してみてください。
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/GettingStarted.Walkthrough.html
ファイル名:tfstate-s3bucket.yml
AWSTemplateFormatVersion: 2010-09-09 Description: CodePipeline For Lambda Deploy Parameters: BucketNameTfstate: Type: String Default: [固有の名前を定義]-tfstate Description: S3 Name for Artifact Resources: tfstateBucket: Type: AWS::S3::Bucket Properties: BucketName: !Ref BucketNameTfstate BucketEncryption: ServerSideEncryptionConfiguration: - ServerSideEncryptionByDefault: SSEAlgorithm: AES256 PublicAccessBlockConfiguration: BlockPublicAcls: True BlockPublicPolicy: True IgnorePublicAcls: True RestrictPublicBuckets: True
2. providers.tfを作成
Terraformソースコードが配置されているディレクトリにproviders.tfを以下の内容で作成する
ファイル名:providers.tf
terraform { required_version ">= [利用するバージョンを記載]" backend "s3" { # 作成したS3バケット bucket = "[S3バケット名]" region = "[リージョン名]" # tfstateファイル名 key = "terraform.tfstate" encrypt = true } } provider "aws" { region = "[リージョン名]" }
(2) tfstateファイル同時書き込みの防止
Terraformでの環境構築実行時には、tfstateファイルへ内容を書き込む必要があります。多数のユーザが同時に書き込みに行くと。。。どうなるか想像つきますよね??
Terraform利用時には、tfstateファイルへの同時操作を禁止する必要があります。
AWSでは、DynamoDBテーブルを利用することでtfstateファイルの利用状況を管理することが可能です。
[手順]
1. tfstate管理用DynamoDBテーブルを作成
tfstate操作状況を管理するためのDynamoDBテーブルは「CloudFormation」にて作成
ファイル名:tfstate-dynamodb.yml
AWSTemplateFormatVersion: 2010-09-09 Description: CodePipeline For Lambda Deploy Parameters: TableNameTfstate: Type: String Default: [固有の名前を定義]-dynamodbTfstate Description: DynamoDB Table Name tfstateDynamoDB: Type: AWS::DynamoDB::Table Properties: TableName: !Ref TableNameTfstate AttributeDefinitions: - AttributeName: "LockID" AttributeType: "S" KeySchema: - AttributeName: "LockID" KeyType: "HASH" ProvisionedThroughput: ReadCapacityUnits: "1" WriteCapacityUnits: "1"
2. providers.tfを以下の内容に変更
ファイル名:providers.tf
terraform { required_version ">= [利用するバージョンを記載]" backend "s3" { # 作成したS3バケット bucket = "[S3バケット名]" region = "[リージョン名]" # tfstateファイル名 key = "terraform.tfstate" encrypt = true # 作成したDynamoDBテーブル dynamodb_table = "[DynamoDBテーブル名]" } } provider "aws" { region = "[リージョン名]" }
3. Terraformソースコードを管理する
「Infrastructure as Code」なので、ソースコードの管理は必須になってきます。GitHubやSubversionなどのバージョン管理システムを用いてソースコードのバージョン管理を実施しましょう。
また、Terraformでは「実環境に何が反映されているのか」を管理することが重要です。
「このブランチへマージされたら必ずterraform applyを実行し、環境にソースコードを適用する。」といった約束事を案件メンバー内で策定しましょう。
AWSでは、CodeCommitを利用することでソースコードのバージョン管理を実現することが可能です。
CodeCommitは、CodePipelineなどのCICDサービスと連携が可能であるため、Terraform用CICDパイプラインの構築が可能です。(ここは、近いうちに別の記事を出し詳細にご説明予定です!)
https://docs.aws.amazon.com/ja_jp/codepipeline/latest/userguide/action-reference-CodeCommit.html
また、GitHubでも「GitHub Actions」を利用することでTerraform用CICDパイプラインの構築が可能ですので、興味のある方はこちらをご一読してみてください。
Automate Terraform with GitHub Actions
まとめ
今回の記事では、「Terraformを管理する」について書いていきました。
次回の記事では、今回の記事で取り上げたtfstateやソースコードの管理を実現するために私が作成した「Terraform利用環境構築テンプレート」を利用したハンズオン記事を書こうと思います。
テックブログ新着情報のほか、AWSやGoogle Cloudに関するお役立ち情報を配信中!
Follow @twitter2024 Japan AWS Top Engineers / Google Cloud Partner Top Engineer 2025 に選出されました! 生成 AI 多めで発信していますが、CI/CDやIaCへの関心も高いです。休日はベースを弾いてます。
Recommends
こちらもおすすめ
-
AWS CodePipelineのエラーを検知し、Backlog自動起票する手順
2023.12.20
Special Topics
注目記事はこちら
データ分析入門
これから始めるBigQuery基礎知識
2024.02.28
AWSの料金が 10 %割引になる!
『AWSの請求代行リセールサービス』
2024.07.16