GitHub ActionsからAzureなどのクラウドサービスにアクセスするユースケースは多いと思います。そのような場合、クラウドサービスのOpen ID Connect(OIDC)を利用することで、GitHub Actions側でシークレットキーを保存する必要がなく、よりセキュアにクラウドサービスにアクセスすることができます。
GitHub ActionsからOIDCを利用して、Azureに対して、Terraformを実行する際、いくつかハマりどころがありましたので、Azure側の設定〜Terraform側の設定についてご紹介します。
Azure側の設定
まずはAcitive Directoryでアプリを登録します。
証明書とシークレットからフェデレーションの資格情報を登録します。Azure上ではこれがOIDC接続の設定になります。
- フェデレーション資格情報のシナリオとして、GitHub Actionsを選択します。
- 組織、リポジトリで対象のGitHub上のリポジトリを入力します。
- エンティティ型ではGitHub Actionsの対象となる環境やブランチを選ぶことができます。
- 最後の項目はエンティティ型よって、選択する内容が変わります。GitHub Actionsの対象となる環境名やブランチ名などを入力します。
設定が完了したら、アプリケーションIDとテナントIDを確認しておきます。後ほどGitHub Actionsで利用します。
最後にsubscription側で作成したアプリに対して、ロールを付与します。
アクセスしたいリソースが存在するsubscriptionのアクセス制御(IAM)からロールの割当を実行します。
選択するロールについては、アクセスしたいリソースについて権限があるものを選びます。ここで注意点として、もしTerraformのtfstateファイルをAzure Blob Storageに保存している場合は、Blob Storageへのアクセス権限(ストレージBLOBデータ所有者等)についても、付与する必要があります。
ロールを付与するユーザについては、先程作成したアプリを指定します。
設定が完了したら、サブスクリプション IDを確認します。こちらも後ほど、GitHub Actionsで利用します。
Azure側の操作は以上となります。
Terraform側の設定
Azure OIDCを利用する場合、backendとproviderに追加の設定が必要となります。
backend.tf では use_oidc
と use_azuread_auth
を設定します。
terraform { backend "azurerm" { resource_group_name = "<Resource Group名>" storage_account_name = "<Storage Account名>" container_name = "<コンテナ名>" key = "terraform.tfstate" use_oidc = true #OIDC接続する場合は必要 use_azuread_auth = true #tfstateをAzure Blob Storageに保存している場合は必要 } }
provider.tf では use_oidc
と skip_provider_registration
の設定が必要になります。
terraform { required_version = ">=1.5.0" required_providers { azurerm = { source = "hashicorp/azurerm" version = ">=3.61.0" } } } provider "azurerm" { use_oidc = true skip_provider_registration = "true" features {} }
Resource Providerを登録していない場合は、TerraformでPlanやApplyを実行した際にエラーになります。エラーを回避するためには、下記のように、Resource Providerを登録するか、 skip_provider_registration
の設定が必要になります。
Terraform側で必要となる設定は以上です。
GitHub Actions
AzureとTerraformの設定が完了したので、GitHub ActionsからTerraformが実行できる準備が整いました。GitHub Actionsのサンプルとしては下記のようになります。
- ARM_CLIENT_IDには上記で確認したアプリケーションIDを設定します。
- ARM_SUBSCRIPTION_IDにはサブスクリプションIDを設定します。
- ARM_TENANT_IDにはテナントIDを設定します。
name: azure-oidc-sample
on: push: branches: [ main ] env: ARM_CLIENT_ID: "${{ secrets.AZURE_CLIENT_ID }}" ARM_SUBSCRIPTION_ID: "${{ secrets.AZURE_SUBSCRIPTION_ID }}" ARM_TENANT_ID: "${{ secrets.AZURE_TENANT_ID }}" permissions: id-token: write contents: read jobs: test: runs-on: ubuntu-latest steps: - name: Checkout to the branch uses: actions/checkout@v3 - uses: hashicorp/setup-terraform@v2.0.3 with: terraform_wrapper: false - name: Check format run: terraform fmt -check -recursive - name: Init run: terraform init -no-color - name: Check validate run: terraform validate - name: Apply run: terraform apply -auto-approve
終わりに
Azure OIDCを利用して、GitHub ActionsからTerraformを実行する方法について紹介しました。AWSのOIDCは設定によっては、セキュリティ的に問題なるケースがありますが、Azure OIDCはGitHubがMicrosoft傘下であることもあり、迷うことなく、簡易に設定できるようになっていると思いました。
OIDCで接続することで、GitHub側にシークレットキーを保存する必要もなく、キーのローテションも不要なため、よりセキュアにクラウドリソースにアクセスできます。今後も活用していきたいと思います。