Infrastructure as Code

インフラをコードで管理する

IaCとは

インフラストラクチャの構成をコードとして定義し、バージョン管理、レビュー、 自動化を可能にするプラクティス。手動設定による不整合やエラーを防ぐ。

IaCツール比較

ツール種類言語対応プロバイダー
Terraform宣言的HCLマルチクラウド
AWS CloudFormation宣言的YAML/JSONAWSのみ
Pulumi命令的/宣言的TypeScript,Python等マルチクラウド
Ansible命令的YAMLマルチクラウド
CDK命令的TypeScript,Python等AWS/他

Terraform 例

1# main.tf
2terraform {
3 required_providers {
4 aws = {
5 source = "hashicorp/aws"
6 version = "~> 5.0"
7 }
8 }
9}
10
11provider "aws" {
12 region = "ap-northeast-1"
13}
14
15resource "aws_vpc" "main" {
16 cidr_block = "10.0.0.0/16"
17
18 tags = {
19 Name = "main-vpc"
20 Environment = "production"
21 }
22}
23
24resource "aws_subnet" "public" {
25 vpc_id = aws_vpc.main.id
26 cidr_block = "10.0.1.0/24"
27 availability_zone = "ap-northeast-1a"
28
29 tags = {
30 Name = "public-subnet"
31 }
32}
33
34output "vpc_id" {
35 value = aws_vpc.main.id
36}

Terraformワークフロー

terraform initプロバイダーのダウンロード、初期化
terraform plan変更内容のプレビュー(dry-run)
terraform apply変更を適用
terraform destroyリソースを削除

状態管理(State)

Terraformは現在のインフラ状態をterraform.tfstateファイルに保存。 チームで共有するにはリモートバックエンドを使用。

1# リモートバックエンド設定
2terraform {
3 backend "s3" {
4 bucket = "my-terraform-state"
5 key = "prod/terraform.tfstate"
6 region = "ap-northeast-1"
7 dynamodb_table = "terraform-locks"
8 encrypt = true
9 }
10}

Ansible 例

1# playbook.yml
2---
3- name: Configure web servers
4 hosts: webservers
5 become: yes
6
7 tasks:
8 - name: Install nginx
9 apt:
10 name: nginx
11 state: present
12 update_cache: yes
13
14 - name: Start nginx
15 service:
16 name: nginx
17 state: started
18 enabled: yes
19
20 - name: Copy nginx config
21 template:
22 src: templates/nginx.conf.j2
23 dest: /etc/nginx/nginx.conf
24 notify: Restart nginx
25
26 handlers:
27 - name: Restart nginx
28 service:
29 name: nginx
30 state: restarted

ベストプラクティス

バージョン管理

IaCコードはGitで管理、PRでレビュー

モジュール化

再利用可能なモジュールに分割

環境の分離

dev/staging/prodは別のstateで管理

シークレット管理

機密情報はVaultやAWS Secrets Managerで管理

drift検出

手動変更との差分を定期的に検出

宣言的 vs 命令的

宣言的(Declarative)

「何が欲しいか」を記述。ツールが現状との差分を計算し適用。

例: Terraform, CloudFormation

命令的(Imperative)

「どうやって作るか」をステップで記述。順番に実行。

例: Ansible, シェルスクリプト