y-ohgi's blog

TODO: ここになにかかく

OpenTofuことはじめ

TL;DR

  • OpenTofuを触る
  • OpenTofuとTerraformの変遷についてざっくり
  • AWSリソースを構築する

About

OpenTofuはTerraformからForkされたIaCツールです。
一定の互換性はありつつ、機能の差異はバージョンを重ねるごとに増えていっています。

ライセンス

2023年8月にTerraformはMPL2.0(Mozilla Public License v2.0)から、BSL1.1(Business Source License v1.1)に変更されました。
BSL1.1は商用利用に制限のあるライセンスになります。
基本的に今まで通りIaCツールとしてユーザーがプロビジョニングする分には問題はなく、例えばマネージドサービスとしてTerraformを提供(再販)する場合に影響が発生します。
MariaDB社が2016年に開発開発したライセンスで、OSSを自社のマネージドサービスとして提供していることがBSL1.1の背景にあります。

TerraformがこのBSL1.1へライセンス変更したことを起因に、TerraformがMPL2.0のライセンスのバージョンからフォークされMPL2.0で開発されているものがOpenTofuになります。
個人的に興味深いのがTerraformとHCL2のメインの開発者である Martin Atkins 氏がHashiCorpを退職し、その後Terraformのコミットを辞め、OpenTofuへのコントリビューションを開始している点です。

OpenTofuはMPL2.0であり、現在はLinux Foundation傘下のプロダクトになります。
そしてOpenTofuは現在CNCFのsandboxプロダクトとしての起票がされており、OpenTofuを選定する基準の1つになると考えます。
[Sandbox] OpenTofu · Issue #81 · cncf/sandbox

Terraformとの互換性

TerraformとOpenTofuはバージョンを重ねるごとに機能が異なり、独自の機能も追加されて行っています。
また、公式からmigrationガイドが出ているのでOpenTofuに移行を検討する場合は機能や構文の差異が大きくならないうちに確認することを推奨します。
Migrating to OpenTofu 1.7.x from Terraform | OpenTofu

Registry

OpenTofuはhashicorpのレジストリー( registry.terraform.io )から別れ、独自に registry.opentofu.org のドメインでホストされています。

Provider Registry Protocol | OpenTofu

How to

Dockerコンテナを起動する

nginxのコンテナを起動するtfファイルを記述します。

demo.tf

terraform {
  required_providers {
    docker = {
      source = "kreuzwerker/docker"
      version = "~> 3.0.1"
    }
  }
}

provider "docker" {}

resource "docker_image" "nginx" {
  name         = "nginx:latest"
  keep_locally = false
}

resource "docker_container" "nginx" {
  image = docker_image.nginx.image_id
  name  = "tutorial"
  ports {
    internal = 80
    external = 8000
  }
}

tofuコマンドで初期化

$ tofu init

applyを実行しコンテナを起動

$ tofu apply
$ docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED         STATUS         PORTS                  NAMES
f9da139d8891   f876bfc1cc63   "/docker-entrypoint.…"   5 seconds ago   Up 4 seconds   0.0.0.0:8000->80/tcp   tutorial

ディレクトリ構成。
registry.opentofu.org レジストリーを参照していることが確認できました。

$ tree . -a
.
├── .terraform
│   └── providers
│       └── registry.opentofu.org
│           └── kreuzwerker
│               └── docker
│                   └── 3.0.2
│                       └── darwin_arm64
│                           ├── CHANGELOG.md
│                           ├── LICENSE
│                           ├── README.md
│                           └── terraform-provider-docker_v3.0.2
├── .terraform.lock.hcl
├── demo.tf
├── terraform.tfstate
└── terraform.tfstate.backup

destoryでコンテナの削除

$ tofu destroy

コンテナが起動していないことを確認

$ docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

Terraformで同じファイルをapplyする

demo.tf 以外のファイルを削除し、terraformで実行確認

$ terraform init
$ terraform apply

registry.terraform.io レジストリーを参照していることを確認できました。

$ tree . -a
.
├── .terraform
│   └── providers
│       └── registry.terraform.io
│           └── kreuzwerker
│               └── docker
│                   └── 3.0.2
│                       └── darwin_arm64
│                           ├── CHANGELOG.md
│                           ├── LICENSE
│                           ├── README.md
│                           └── terraform-provider-docker_v3.0.2
├── .terraform.lock.hcl
├── demo.tf
└── terraform.tfstate

VPCを構築する

vpc.tf

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws" # ここであえて "hashicorp/aws" を宣言
      version = "~> 5.0"
    }
  }
}

# Configure the AWS Provider
provider "aws" {
  region = "ap-northeast-1"
}

# Create a VPC
resource "aws_vpc" "example" {
  cidr_block = "10.0.0.0/16"
}
$ tofu init
$ tofu plan

treeコマンドで確認したところ、providerが自動的に registry.opentofu.org を参照している。

$ tree . -a
.
├── .terraform
│   └── providers
│       └── registry.opentofu.org
│           └── hashicorp
│               └── aws
│                   └── 5.82.2
│                       └── darwin_arm64
│                           ├── CHANGELOG.md
│                           ├── LICENSE
│                           ├── README.md
│                           └── terraform-provider-aws
├── .terraform.lock.hcl
└── vpc.tf
terraform {
  required_providers {
    aws = {
      source  = "opentofu/aws" # "hashicorp/aws" から書き換え
      version = "~> 5.0"
    }
  }
}

# Configure the AWS Provider
provider "aws" {
  region = "ap-northeast-1"
}

# Create a VPC
resource "aws_vpc" "example" {
  cidr_block = "10.0.0.0/16"
}
$ tofu init
$ tree . -a
.
├── .terraform
│   └── providers
│       └── registry.opentofu.org
│           ├── hashicorp
│           │   └── aws
│           │       └── 5.82.2
│           │           └── darwin_arm64
│           │               ├── CHANGELOG.md
│           │               ├── LICENSE
│           │               ├── README.md
│           │               └── terraform-provider-aws
│           └── opentofu
│               └── aws
│                   └── 5.82.2
│                       └── darwin_arm64
│                           ├── CHANGELOG.md
│                           ├── LICENSE
│                           ├── README.md
│                           └── terraform-provider-aws
├── .terraform.lock.hcl
└── vpc.tf

ライセンスが気になったので確認したところ、両方ともMPL2.0

$ head .terraform/providers/registry.opentofu.org/hashicorp/aws/5.82.2/darwin_arm64/LICENSE
Copyright (c) 2017 HashiCorp, Inc.

Mozilla Public License Version 2.0
==================================

1. Definitions
--------------

1.1. "Contributor"
    means each individual or legal entity that creates, contributes to
$ head .terraform/providers/registry.opentofu.org/opentofu/aws/5.82.2/darwin_arm64/LICENSE
Copyright (c) 2017 HashiCorp, Inc.

Mozilla Public License Version 2.0
==================================

1. Definitions
--------------

1.1. "Contributor"
    means each individual or legal entity that creates, contributes to

terraformレジストリーの方も気になったので確認したところMPL2.0でした。

$ terraform init
$ head .terraform/providers/registry.terraform.io/hashicorp/aws/5.82.2/darwin_arm64/LICENSE.txt
Copyright (c) 2017 HashiCorp, Inc.

Mozilla Public License Version 2.0
==================================

1. Definitions
--------------

1.1. "Contributor"
    means each individual or legal entity that creates, contributes to

Refs

所感

OpenTofuとTerraformの一定の互換性があるものの、やはり別の道を進むのだと感じました。
別々の機能が実装されつつある今、強い言葉を使うなら「TerraformからOpenTofuに移行するちょうど良いタイミング」なのかなと感じました。