最近、インフラリソース構築にはもっぱら Terraform を使っています。
以前の記事で触れた Ansible のように IaC (Infrastructure as Code) を実現するツールで、手動運用になりがちなインフラリソースの構築を自動化し、冪等性を担保できるようになります。

インターネットで調べると AWS 構築関連のものが多くヒットしますが、実は別のクラウド(Azure とか GCP)や GitHub の設定なんかもできたりします。
AWS 構築系は他の記事にお任せするとして、今回は GitHub の Action Secrets に値を設定するコードを書いてみます。

準備

まずは Terraform CLI をインストールします。
※バージョンを切り替えられる tfenv を利用するという方法もありますが、今回は利用しません。

以下コマンドでバージョンが出力されれば OK です。

$ terraform -version # 以下は出力の例
Terraform v1.0.6
on linux_amd64

Your version of Terraform is out of date! The latest version
is 1.0.8. You can update by downloading from https://www.terraform.io/downloads.html

ファイル作成

次に以下のようなファイルを作成し main.tf として保存します。

terraform {
  required_version = "~> 1.0"

  required_providers {
    github = {
      source  = "integrations/github"
      version = "~> 4.0"
    }
  }
}

provider "github" {} # 利用する provider を定義

resource "github_actions_secret" "test_secret" {
  repository       = "my-repository" # 設定したいリポジトリ名
  secret_name      = "BY_TERRAFORM" # secrets 名
  plaintext_value  = var.by_terraform_secret # 秘匿情報になるので外部から値を設定できるようにする
}

外部から値を設定するため、以下ファイルを作成し variables.tf として保存します。

variable "by_terraform_secret" {}

個人アクセストークン作成

今回は GitHub の設定を変更するため、それが可能な権限である必要があります。
こちらを参考にトークンを発行してください。
作成時は repo にチェックが入っていれば移行の手順が実施できるはずです。

トークン発行後、環境変数に設定します。

export GITHUB_USER='<ユーザー名>'
export GITHUB_TOKEN='<発行したトークン>'

コマンド実行

Terraform の実行は、以下のような流れが基本です。

  • terraform init で初期化(すでに実施済みの場合は不要)
  • terraform plan で適用される変更点を確認
  • terraform apply で適用

terraform init

$ terraform init # 以下のような出力がされれば OK
Initializing the backend...

Initializing provider plugins...
- Finding integrations/github versions matching "~> 4.0"...
- Installing integrations/github v4.16.0...
- Installed integrations/github v4.16.0 (signed by a HashiCorp partner, key ID xxxx)

Partner and community providers are signed by their developers.
If you'd like to know more about provider signing, you can read about it here:
https://www.terraform.io/docs/cli/plugins/signing.html

Terraform 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 Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.

Terraform has been successfully initialized!

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

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

この時、コマンドを実行したディレクトリに terraform.tfstate ファイルが作成されます。
これが state ファイルです。
このファイルは原則バージョン管理には含めません(秘匿情報などがそのまま記述されるため)。

terraform plan

$ terraform plan
var.by_terraform_secret
  Enter a value: # 値の入力を求められるので、入力して Enter


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

Terraform will perform the following actions:

  # github_actions_secret.test_secret will be created
  + resource "github_actions_secret" "test_secret" {
      + created_at      = (known after apply)
      + id              = (known after apply)
      + plaintext_value = (sensitive value)
      + repository      = "my-repository"
      + secret_name     = "BY_TERRAFORM"
      + updated_at      = (known after apply)
    }

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

結果、1つのリソースが追加されることがわかります。

terraform apply

$ terraform apply
var.by_terraform_secret
  Enter a value: # 再度値を入力する


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

Terraform will perform the following actions:

  # github_actions_secret.test_secret will be created
  + resource "github_actions_secret" "test_secret" {
      + created_at      = (known after apply)
      + id              = (known after apply)
      + plaintext_value = (sensitive value)
      + repository      = "my-repository"
      + secret_name     = "BY_TERRAFORM"
      + updated_at      = (known after apply)
    }

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

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

github_actions_secret.test_secret: Creating...
github_actions_secret.test_secret: Creation complete after 2s [id=my-repository:BY_TERRAFORM]

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

実行結果確認

最後に GitHub で対象リポジトリの Settings > Secrets で追加されていることを確認します。

まとめ

かなりざっくりとですが Terraform の導入について書きました。
今回は Action Secrets の設定のみでしたが、他にも設定できる項目はたくさんあります。
また、現状 state ファイルはローカルにあると思いますが、管理の煩雑さを解消するため S3 や Terraform Cloud を利用するという方法があります。
これについては次回書きます(→書きました)。

今回遊んだリポジトリはこちら。