今回は、既存のGitHub Organizationの全リポジトリをTerraformに同時にインポート・コード化する方法をご紹介します。
Terraformで1つ1つのGitHubリポジトリをインポートするのは手間がかかるため、Terraformerというツールを使用します。
注意:TerraformerはGitHub個人アカウントには対応しておらず、GitHub Organizationアカウントのみに対応しています。
Terraformerとは
既存のクラウドリソースからTerraformのファイルを自動作成するOSSのツールです。
https://github.com/GoogleCloudPlatform/terraformer
Terraformerは40種類以上のクラウドサービスに対応しています。
今回ご紹介するGitHubの他にも、AWSやNew Relic等、多様なサービスに対応しています。
構成図
構成図は以下です。
Terraformerを用いて、GitHub OrganizationのリポジトリをTerraformのコードにします。
Terraofrmのコードを格納する管理用リポジトリ自身もGitHubリポジトリとしてコード化対象とします。
tfstateファイルのバックエンドとして、AWSのS3バケット・DynamoDBテーブルを作成します。
作成方法は以下の記事をご参照ください。
Terraformのバージョン情報
今回は以下のバージョンで作業しました。
・Terraform本体のバージョン:1.3.5
・GitHubのプロバイダバージョン:5.9.1
Terraformerで既存のGitHubのリポジトリをインポートする手順
Terraformerで既存のGitHubリポジトリをインポートした手順は以下です。
AWSでの作業
- Terraformのバックエンド用のS3バケット・DynamoDBテーブル作成
詳細な手順は以下をご覧ください。
GitHubでの作業
- Terraformのコード管理用のリポジトリ作成
GitHub上に、Terraformのコード管理用のリポジトリを作成します。
※この管理用リポジトリ自身もTerraformのコード化対象とします。
- アクセストークンの生成
GitHub画面右上のプロフィールアイコンを押下して、[Settings]を押下します。
[Developer settings]を押下します。
[Personal access tokens]>[Tokens(classic)]を押下して、[Generate new token(classic)]を押下します。
[repo」と[delete_repo]にチェックして、[Generate token]を押下し、生成されたトークンの値を控えておきます。
ローカルでの作業
- AWS CLIのインストール・セットアップ
AWS CLIをインストールしてセットアップします。
バックエンドのS3バケット・DynamonDBテーブルを作成したAWSアカウントのアクセスキー・シークレットアクセスキーをAWS CLI上に設定しておきます。
詳細な手順は公式ドキュメントをご参照ください。 - Terraformのインストール
Terraformをインストールします。
詳細は割愛しますが、筆者はtfenvというTerraformのバージョン管理ツールでTerraformをインストールしました。 - 管理用リポジトリをローカルにクローン
GitHubでの作業で作成した管理用リポジトリをローカルのGitでクローンします。 - Terraformの動作設定
ローカルの管理用リポジトリに、Terraform実行用のディレクトリを作成します。
※命名は任意【例】terraform
Terraform実行用ディレクトリ内に、Terraform動作設定ようのtfファイルを作成します。
※命名は任意【例】terraform-config.tf
ここでTerraform本体だけでなく、GitHubのプロバイダバージョンや、アクセストークンも設定しています。
▼terraform-config.tf############################################################################ # プロバイダ設定 ############################################################################ # Configure the GitHub Provider provider "github" { token = var.token } terraform { required_providers { github = { source = "integrations/github" version = "~> 5.0" } } } ############################################################################ # バックエンド設定 ############################################################################ terraform { backend "s3" { bucket = "<バックエンド用に作成したs3バケットの名前>" key = "state/github/terraform.tfstate" encrypt = true region = "ap-northeast-1" dynamodb_table = "<バックエンド用に作成したDynamoDBテーブルの名前>" } }
- Terraformの変数設定
Terraformの実行用ディレクトリ内に、変数の中身を定義するtfvarsファイルを作成します。
このファイルに、GitHubの作業で生成したアクセストークンの値を記述します。
※命名は任意【例】terraform.tfvars
▼terraform.tfvarstoken = "<アクセストークンの値>"
同じくterraformの実行用ディレクトリに、変数名を定義するtfファイルを作成します。
※命名は任意【例】variables.tf
▼variables.tfvariable "token" {}
- Terraformerのインストール
筆者のローカル環境はWindows上のGit Bashのため、以下の手順でTerraformerをインストールしました。
①以下リンクから、latestの「terraformer-github-windows-amd64.exe」をダウンロードします。
https://github.com/GoogleCloudPlatform/terraformer/releases
※ダウンロード先は任意【例】/c/Users/<ログインしているユーザ名>/.terraformer
②GitBashにて、以下コマンドを実行してterraformerのexeファイルのパスを通します。
export PATH=$PATH:/c/Users/<ログインしているユーザ名>/.terraformer
③ダウンロードした「terraformer-github-windows-amd64.exe」を「terraformer.exe」にリネームします。 - Terraform実行用ディレクトリでTerraformを初期化
terraform実行用ディレクトリでterraform init
を実行してTerraformを初期化(バックエンド設定・GitHubプロバイダのインストール)します。 - Terraformerで既存のGitHubリポジトリをterraformにインポート
Terraform実行用ディレクトリで以下コマンドを実行します。
terraformer import github --owner=dogharasu --resources=repositories --token=<GitHubの作業で生成したアクセストークンの値>
- Terraformerの実行結果を確認
Terraform実行用ディレクトリ配下に、「generated/github/<GitHub Organizationアカウント名>/repositories」の階層が作成されます。
ちなみに個人アカウントの階層も作成されますが、インポートは非対応のためファイルが無い空のディレクトリとなっています。
- インポート・コード化されたリソースを確認
「generated/github/<GitHub Organizationアカウント名>/repositories/repository.tf」に組織アカウントの全てのリポジトリリソースがコード化されています。
リソース名は自動で「tfer–<リポジトリ名>」となるため、任意のリソース名にしたい場合は、terraform state mvでリソース名を変更する必要がありそうです。
ここでは割愛しますが、リポジトリのコラボレーターについても「repository_collaborator.tf」にコード化されます。
また、各リソースのアウトプットも「outputs.tf」にコード化されます。 - インポートされたリソースをバックエンドのS3・DynamonDBへ移行
Terraformerでインポートを実行すると、ローカルにtfstateファイルが生成されるため、これをバックエンドのS3・DynamonDBへ移行します。「generated/github/<GitHub Organizationアカウント名>/repositories/provider.tf」をterraform動作設定に作成していたtfファイル(筆者だとterraform-config.tf)の内容で上書きします。「generated/github/<GitHub Organizationアカウント名>/repositories」配下に、変数の中身を定義するtfvarsファイル(筆者だとterraform.tfvars」、変数名を定義するtfファイル(筆者だとvariables.tf)を配置します。
各ファイルの内容は前述で作成したものと同じです。「generated/github/<GitHub Organizationアカウント名>/repositories」でterraform init
を実行すると、yes or no で問われるため、yesを入力します。
注意:使用しているTerraformのバージョンがterrafomer対応のバージョン(0.13)より新しいと、tfstateファイルの記述形式が古い扱いとなり、エラーになることがあります。│ Error: Invalid legacy provider address │ │ This configuration or its associated state refers to │ the unqualified provider "github". │ │ You must complete the Terraform 0.13 upgrade process │ before upgrading to later versions.
このエラーを解消するには、以下コマンドを実行して、使用しているTeraformのバージョン用にtfstateファイルを更新し、再度
terraform init
を実行します。
terraform state replace-provider \
-auto-approve \
"registry.terraform.io/-/github"\
"registry.terraform.io/hashicorp/github"
- インポートされたコードでTerraformを実行できるか確認
「generated/github/<GitHub Organizationアカウント名>/repositories」で、terraform plan
を実行すると、以下のエラーが出力されます。│ Error: "private": conflicts with visibility
terraform実行時には不要な属性もインポートされているため、不要な以下の記述を「generated/github/<GitHub Organizationアカウント名>/repositories/repository.tf」から削除します。visibility = "private"
「generated/github/<GitHub Organizationアカウント名>/repositories」でterraform plan
を実行して、差分がないことを確認します。
注意:terraform planの結果で警告が出力されます。
GitHubプロバイダのバージョンが新しいものを使っているため、推奨のパラメータが更新されている影響と思われます。
適宜、推奨のパラメータに書き換えが必要ですが、terraform applyは実行可能です。 - コードの階層の移行
以下のtfファイルを、自身が作成していたTerraform実行用ディレクトリに移動 or コピーすれば、作業は完了です。
「generated/github/<GitHub Organizationアカウント名>/repositories/repository.tf」
「generated/github/<GitHub Organizationアカウント名>/repositories/outputs.tf」
「generated/github/<GitHub Organizationアカウント名>/repositories/repository_collaborator.tf」
まとめ
今回は、TerraformのインポートツールであるTerraformerを用いて、GitHub Organizationのリポジトリをインポートする方法をご紹介しました。
筆者の方法だと、GitHubリポジトリを管理するリポジトリ自身もコード化対象していますのでご注意ください(管理用のリポジトリは別管理の方が好ましいように思えます)。
この記事が少しでも、GitHubリソースのコード化のお役に立てれば幸いです。
参考情報
https://qiita.com/nakamasato/items/d12a3d5362dbd8a70299