🍲

湯豆腐好きなので OpenTofu を触ってみた

2023/12/24に公開

はじめに

寒くなると毎日お鍋を食べたい筆者が特に好きなお鍋は「湯豆腐」なので、Terraform をフォークした OpenTofu を触ってみたのでメモしておきます。

この記事は、毎度お馴染みの YAMAP エンジニア Advent Calendar 2023 十六日目の記事です。

https://qiita.com/advent-calendar/2023/yamap-engineers

OpenTofu とは

Terraform のライセンスが OSS ライセンスではなくなったタイミングで、有志によってフォークされた OSS プロジェクトです。

https://opentofu.org/docs/intro/

Linux Foundation 傘下で開発が進められており、最近では OpenTofu v1.6.0-rc1 がリリースされたというニュースが報じられました。

https://www.linuxfoundation.org/blog/opentofu-release-candidate-is-out

尚、OpenTofu ドキュメントの FAQ には以下のように記述されており、Terraform 1.5.x との互換を謳っています。

What are the differences between OpenTofu and Terraform?
There will be no differences between Terraform (1.5.x versions) and OpenTofu. As new versions are released, this will change.

今後の OpenTofu のバージョンについて、Terraform との互換性が維持されるかどうかについても以下のように書かれています。

Will OpenTofu be compatible with future Terraform releases?
The community will decide what features OpenTofu will have. Some long-awaited Terraform features will be publicly available soon.

Some companies have pledged to pay for full-time engineers to work on OpenTofu. We have 19 such engineers involved already — and many other individuals, companies, projects, and foundations are prepared to contribute.

方針は OSS コミュニティにより決定されるが、個人や企業等の貢献が OpenTofu の今後を担っているということでしょうか。

インストール

ということで、今回は以下の環境に OpenTofu をインストールして触っていこうと思います。

$ sw_vers
ProductName:            macOS
ProductVersion:         14.0
BuildVersion:           23A344

インストールはドキュメントによると macOS には Homebrew でインストールすることが出来るようです。

https://opentofu.org/docs/intro/install/homebrew

$ brew install opentofu

インストールしたらバージョンを確認してみます。

$ tofu version
OpenTofu v1.6.0-rc1
on darwin_amd64

ヘルプも実行してみます。

$ tofu -help
Usage: tofu [global options] <subcommand> [args]

The available commands for execution are listed below.
The primary workflow commands are given first, followed by
less common or more advanced commands.

Main commands:
  init          Prepare your working directory for other commands
  validate      Check whether the configuration is valid
  plan          Show changes required by the current configuration
  apply         Create or update infrastructure
  destroy       Destroy previously-created infrastructure

All other commands:
  console       Try OpenTofu expressions at an interactive command prompt
  fmt           Reformat your configuration in the standard style
  force-unlock  Release a stuck lock on the current workspace
  get           Install or upgrade remote OpenTofu modules
  graph         Generate a Graphviz graph of the steps in an operation
  import        Associate existing infrastructure with a OpenTofu resource
  login         Obtain and save credentials for a remote host
  logout        Remove locally-stored credentials for a remote host
  metadata      Metadata related commands
  output        Show output values from your root module
  providers     Show the providers required for this configuration
  refresh       Update the state to match remote systems
  show          Show the current state or a saved plan
  state         Advanced state management
  taint         Mark a resource instance as not fully functional
  test          Execute integration tests for OpenTofu modules
  untaint       Remove the 'tainted' state from a resource instance
  version       Show the current OpenTofu version
  workspace     Workspace management

Global options (use these before the subcommand, if any):
  -chdir=DIR    Switch to a different working directory before executing the
                given subcommand.
  -help         Show this help output, or the help for a specified subcommand.
  -version      An alias for the "version" subcommand.

AWS Provider を使ってみる

OpenTofu では、Terraform で提供されている各種プロバイダを利用することが可能なので、AWS Provider を使って S3 バケットを作ってみたいと思います。

https://registry.terraform.io/providers/hashicorp/aws/latest/docs

以下のように main.tf を用意しました。

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

provider "aws" {
  region = "ap-northeast-1"
}

resource "aws_s3_bucket" "tofu" {
  bucket = "my-tofu-backet-2023"

  tags = {
    Name        = "My my-tofu-backet-2023"
  }
}

一通り、apply するまでのステップを試してみたいと思います。

まずは、fmt コマンドで main.tf のフォーマットを整形します。

$ tofu fmt
main.tf

次に varidate を実行します。

$ tofu validate
╷
│ Error: Missing required provider
│
│ This configuration requires provider registry.opentofu.org/hashicorp/aws, but that provider isn't available. You may be able to install it automatically by running:
│   tofu init

ああ、すいません。init を実行する必要がありました。

$ tofu init
Initializing the backend...

Initializing provider plugins...
- Finding hashicorp/aws versions matching "~> 5.0"...
- Installing hashicorp/aws v5.31.0...
- Installed hashicorp/aws v5.31.0 (signed, key ID 0C0AF313E5FD9F80)

Providers are signed by their developers.
If you'd like to know more about provider signing, you can read about it here:
https://opentofu.org/docs/cli/plugins/signing/

OpenTofu has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that OpenTofu can guarantee to make the same selections by default when
you run "tofu init" in the future.

OpenTofu has been successfully initialized!

You may now begin working with OpenTofu. Try running "tofu plan" to see
any changes that are required for your infrastructure. All OpenTofu commands
should now work.

If you ever set or change modules or backend configuration for OpenTofu,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

続いて、validate を実行します。

$ tofu validate
Success! The configuration is valid.

良い感じです。続いて、plan を実行してみます。

$ tofu plan -no-color

OpenTofu used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

OpenTofu will perform the following actions:

  # aws_s3_bucket.tofu will be created
  + resource "aws_s3_bucket" "tofu" {
      + acceleration_status         = (known after apply)
      + acl                         = (known after apply)
      + arn                         = (known after apply)
      + bucket                      = "my-tofu-backet-2023"
      + bucket_domain_name          = (known after apply)
      + bucket_prefix               = (known after apply)
      + bucket_regional_domain_name = (known after apply)
      + force_destroy               = false
      + hosted_zone_id              = (known after apply)
      + id                          = (known after apply)
      + object_lock_enabled         = (known after apply)
      + policy                      = (known after apply)
      + region                      = (known after apply)
      + request_payer               = (known after apply)
      + tags                        = {
          + "Name" = "My my-tofu-backet-2023"
        }
      + tags_all                    = {
          + "Name" = "My my-tofu-backet-2023"
        }
      + website_domain              = (known after apply)
      + website_endpoint            = (known after apply)
    }

Plan: 1 to add, 0 to change, 0 to destroy.

──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Note: You didn't use the -out option to save this plan, so OpenTofu can't guarantee to take exactly these actions if you run "tofu apply" now.

最後に apply しましょう。

$ tofu apply -no-color -auto-approve

OpenTofu used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

OpenTofu will perform the following actions:

  # aws_s3_bucket.tofu will be created
  + resource "aws_s3_bucket" "tofu" {
      + acceleration_status         = (known after apply)
      + acl                         = (known after apply)
      + arn                         = (known after apply)
      + bucket                      = "my-tofu-backet-2023"
      + bucket_domain_name          = (known after apply)
      + bucket_prefix               = (known after apply)
      + bucket_regional_domain_name = (known after apply)
      + force_destroy               = false
      + hosted_zone_id              = (known after apply)
      + id                          = (known after apply)
      + object_lock_enabled         = (known after apply)
      + policy                      = (known after apply)
      + region                      = (known after apply)
      + request_payer               = (known after apply)
      + tags                        = {
          + "Name" = "My my-tofu-backet-2023"
        }
      + tags_all                    = {
          + "Name" = "My my-tofu-backet-2023"
        }
      + website_domain              = (known after apply)
      + website_endpoint            = (known after apply)
    }

Plan: 1 to add, 0 to change, 0 to destroy.
aws_s3_bucket.tofu: Creating...
aws_s3_bucket.tofu: Creation complete after 3s [id=my-tofu-backet-2023]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

terraform コマンドと何の遜色なく S3 バケットを作成することが出来ました。続いて、リソースを削除する destroy も試します。

$ tofu destroy -no-color
aws_s3_bucket.tofu: Refreshing state... [id=my-tofu-backet-2023]

OpenTofu used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  - destroy

OpenTofu will perform the following actions:

  # aws_s3_bucket.tofu will be destroyed
...
Plan: 0 to add, 0 to change, 1 to destroy.

Do you really want to destroy all resources?
  OpenTofu will destroy all your managed infrastructure, as shown above.
  There is no undo. Only 'yes' will be accepted to confirm.

  Enter a value: yes

aws_s3_bucket.tofu: Destroying... [id=my-tofu-backet-2023]
aws_s3_bucket.tofu: Destruction complete after 0s

Destroy complete! Resources: 1 destroyed.

こちらも、terraform と何ら違いがありませんね。

以上

簡単に OpenTofu を触ってみました。シンプルなコードでしたが、コードに何の変更を加えることなく Terraform と同じオペレーションでクラウドリソースを操作することが出来ました。個人的に Terraform から乗り換える予定はありませんが、今後も注目したい OpenTofu でした。今夜は湯豆腐にしたいと思います。

参考

https://opentofu.org/docs/intro/

https://qiita.com/minamijoyo/items/16d1b5b15a60d17e350a

https://devops-blog.virtualtech.jp/entry/20230927/1695782657

https://zenn.dev/yuta28/articles/fork-opentf-from-terraform

YAMAP テックブログ

Discussion