インフラの管理をIaC化!AWSでOpenTofuを実行する方法
2024.11.12
最近ではよく Infrastructure as Code(以後IaC)という単語を聞くようになりました。
本記事では、そんなIaCの中でも人気のTerraformからフォークされたOpenTofuの概要と、Dockerさえ入っていればどこでも実行できるOpenTofuの実行方法をご紹介します。
はじめに
皆様はIaC化していますか?最近ではインフラの管理をIaCで行うのが主流となっています。
そこで今回は、HashiCorp(ハシコープ)社が提供するTerraformからフォークされたオープンソースソフトウェア(OSS)であるOpenTofuについて解説していきたいと思います。
記事前半ではOpenTofuのご紹介を、後半では実際にOpenTofuでのAWSリソースの作り方をお伝えするので、ぜひじっくりとご覧ください。
OpenTofu(オープントーフ)とは?
2023年、IaCの中でも人気があったTerraformがOSSからのライセンスの変更を行いました。これに伴いOSSとしてTerraformからフォークされたものがOpenTofuになります。
OpenTofuはIaCとしての構文などはTerraformとほぼ同じなのでTerraformを触ったことのある方であれば楽に書けると思います。
ではそんなOpenTofu/Terraform ですがどのような魅力があるのでしょうか?私が思うOpenTofu/Terraformの利点は以下です。
他にもありますがOpenTofu/Terraformを選択する上で1番の魅力はこの2つだと思っています。ここからは実践形式でOpenTofuについてご紹介していきたいと思います。
OpenTofuの実行環境の種類
OpenTofu/Terraformを実行する際には大きく分けて以下の2つの実行環境があります。
「直接インストールして実行する」は実行する環境ごとにインストール手順を行う必要があります。
そのためここではDockerさえ入っていればどこでも実行できる「インストールされたコンテナイメージ上で実行する」をご紹介します。
「直接インストールして実行する」を行いたい方はOpenTofu公式サイトのこちらを参考にしてください。
OpenTofuの実行環境を準備
では、OpenTofuがインストールされたコンテナイメージを使っていきたいと思います。ここでは以下の環境での実行例を紹介します。
以下のコマンドでOpenTofuの最新のコンテナイメージを取得します。
docker pull ghcr.io/opentofu/opentofu:latest
次に、最低限の設定を書いたmain.tfを作成します。
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.70.0"
}
}
}
provider "aws" {
region = "ap-northeast-1"
default_tags {
tags = {
create = "terraform"
}
}
}
locals {
name_prefix = "tofu-test"
}
data "aws_availability_zones" "all_az" {
filter {
name = "zone-type"
values = ["availability-zone"]
}
}
# VPC作成
resource "aws_vpc" "main" {
cidr_block = "192.168.56.0/24"
tags = {
Name = "${local.name_prefix}-vpc"
}
}
次に以下のコマンドを実行してください。
docker run \
--workdir=/srv/workspace \
--mount type=bind,source=.,target=/srv/workspace \
ghcr.io/opentofu/opentofu:latest \
init
実行すると、以下のファイルが実行ディレクトリに自動で生成されます。
AWSクレデンシャルの設定
それでは次に、AWSの認証情報を設定する方法について説明します。
コンテナ内でデプロイコマンドを実行するためAWS認証情報を渡すためには工夫が必要になります。今回はコンテナ実行時に環境変数として認証情報を渡す方式を採用します。
IAMユーザのアクセスキー/シークレットアクセスキーを使用して認証を行っている方は以下のコマンドを実行します。
docker run \
--workdir=/srv/workspace \
--env AWS_ACCESS_KEY_ID="〓アクセスキー〓" \
--env AWS_SECRET_ACCESS_KEY="〓シークレットアクセスキー〓" \
--mount type=bind,source=.,target=/srv/workspace \
ghcr.io/opentofu/opentofu:latest \
plan -out=main.plan
IAM Identity Centerでの認証を使用している場合は以下のコマンドを実行します。
docker run \
--workdir=/srv/workspace \
--env AWS_ACCESS_KEY_ID="〓アクセスキー〓" \
--env AWS_SECRET_ACCESS_KEY="〓シークレットアクセスキー〓" \
--env AWS_SESSION_TOKEN="〓セッショントークン〓" \
--mount type=bind,source=.,target=/srv/workspace \
ghcr.io/opentofu/opentofu:latest \
plan -out=main.plan
以下のようなログが表示されます。
Webサーバの構築
では最後に実際にOpenTofuを使ってリソースを作成してみましょう。今回はサンプルコードとしてAmazon EC2を使ったWebサーバを構築します。
以下がサンプルコードの続きになります。
# VPC作成
resource "aws_vpc" "main" {
cidr_block = "192.168.0.0/24"
tags = {
Name = "${local.name_prefix}-vpc"
}
}
## ここから下を追記してください
# VPCからサブネットをさらに作成
resource "aws_subnet" "main" {
vpc_id = aws_vpc.main.id
cidr_block = "192.168.0.0/26"
tags = {
Name = "${local.name_prefix}-subnet"
}
}
resource "aws_internet_gateway" "main" {
vpc_id = aws_vpc.main.id
tags = {
Name = "${local.name_prefix}-igw"
}
}
resource "aws_route_table" "main" {
vpc_id = aws_vpc.main.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.main.id
}
route {
cidr_block = aws_vpc.main.cidr_block
gateway_id = "local"
}
}
resource "aws_route_table_association" "main" {
subnet_id = aws_subnet.main.id
route_table_id = aws_route_table.main.id
}
# EC2インスタンス用のパブリックAMIを取得
data "aws_ami" "ubuntu" {
most_recent = true
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*"]
}
filter {
name = "virtualization-type"
values = ["hvm"]
}
owners = ["099720109477"] # Canonical
}
resource "aws_instance" "web" {
ami = data.aws_ami.ubuntu.id
instance_type = "t3.micro"
subnet_id = aws_subnet.main.id
security_groups = [aws_security_group.main.id]
associate_public_ip_address = true
# ユーザデータの内容は不要なスペースを入れないように左揃えにしてください
user_data = < /var/www/html/index.html
EOF
tags = {
Name = "${local.name_prefix}-ec2"
}
}
# セキュリティグループを作成
resource "aws_security_group" "main" {
name = "${local.name_prefix}-sg"
vpc_id = aws_vpc.main.id
tags = {
Name = "${local.name_prefix}-sg"
}
}
resource "aws_vpc_security_group_ingress_rule" "allow_http" {
security_group_id = aws_security_group.main.id
cidr_ipv4 = "〓WebサイトにアクセスするグローバルIPアドレス〓/32" # 誰でもアクセスできてよいのであれば0.0.0.0/0でも問題ないです
ip_protocol = "tcp"
from_port = 80
to_port = 80
tags = {
Name = "${local.name_prefix}-http-ingress-rule"
}
}
resource "aws_vpc_security_group_egress_rule" "main" {
security_group_id = aws_security_group.main.id
cidr_ipv4 = "0.0.0.0/0"
ip_protocol = -1
tags = {
Name = "${local.name_prefix}-egress-rule"
}
}
# 画面表示用
output "ec2_ip" {
value = aws_instance.web.public_ip
}
上記のコードを保存した後に、以下のコマンドを実行します。
# 変更内容を再度出力します
docker run \
--workdir=/srv/workspace \
--env AWS_ACCESS_KEY_ID="〓アクセスキー〓" \
--env AWS_SECRET_ACCESS_KEY="〓シークレットアクセスキー〓" \
--mount type=bind,source=.,target=/srv/workspace \
ghcr.io/opentofu/opentofu:latest \
plan -out=main.plan
# 上のコマンドで出力した内容をデプロイします
docker run \
--workdir=/srv/workspace \
--env AWS_ACCESS_KEY_ID="〓アクセスキー〓" \
--env AWS_SECRET_ACCESS_KEY="〓シークレットアクセスキー〓" \
--mount type=bind,source=.,target=/srv/workspace \
ghcr.io/opentofu/opentofu:latest \
apply "/srv/workspace/main.plan"
※ IAM Identity Centerでの認証を使用している方はAWS_SESSION_TOKENを追加してください
実行後に以下のようなログが出力されれば成功です。
※ IPアドレス部分に関しては塗りつぶしております
数分待ってから、ブラウザで出力されたIPアドレスにアクセスしてみます。以下のようなページが表示されれば成功です。
最後に、以下のコマンドで作成したリソースの削除を行います。
# リソースの全削除を行います
docker run \
--workdir=/srv/workspace \
--env AWS_ACCESS_KEY_ID="〓アクセスキー〓" \
--env AWS_SECRET_ACCESS_KEY="〓シークレットアクセスキー〓" \
--mount type=bind,source=.,target=/srv/workspace \
ghcr.io/opentofu/opentofu:latest \
destroy -auto-approve
※ IAM Identity Centerでの認証を使用している方はAWS_SESSION_TOKENを追加してください
以下のようなログが出力されれば削除完了です。
まとめ
今回はOpenTofuについてご紹介しました。初めての方にもOpenTofuの概要が理解していただけたのではないでしょうか?
使ったことはないけどIaCが気になっていた方やTerraformは使っているけどOpenTofuは使ったことのない方は、この機会にぜひ試してみてください。
最後に宣伝にはなりますが、弊社では24時間365日の有人体制でAWSの監視・運用・管理をまとめてご依頼いただけるサービスをご提供しています。
障害が発生した場合、原因の切り分けから実際の復旧作業まで実施することもできるため、夜間休日の障害でも安心です。
また、JIG-SAWからAWSをご契約いただくとAWSの利用料が割引でご利用いただく事も可能です。
利用料の割引だけでなく様々な無料特典もつき、システム構築や監視・運用、セキュリティサポートなど各種オプションサービスもご用意しておりますので、ぜひお気軽にご相談ください。