0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Terraform CloudをAzureで使ってみた

Last updated at Posted at 2022-12-18

bitFlyer Advent Calendar 2022の18日目のエントリです。
こんにちは。最近はお家時間のQoLを上げるためDIYにハマって、玄関に棚を増設したりしている、bitFlyer SRE部の遠地(とおち)です。
本記事では、Terraform CloudをAzure向けに構築しましたのでその知見をシェアしたいと思います。

tl;dr

  • 「開発と運用の職務分離」や「最小権限の原則」のために、Terraform Cloudの設定自体をコード化
  • いくつかの落とし穴回避ポイント
    • ドメインapp.terraform.ioを社内プロキシの対象から外す
    • Azure DevOpsのApplicationの追加はProject Collection Administrator権限を持ったユーザで行う
    • Terraform CloudのユーザはActive Directory側で定義
  • Terraform Cloudにprojectの概念が欲しかった日々だった

背景

令和ちゃん四さいが気圧スライダーで遊んでいる昼下がり。とあるSREエンジニアは頭を抱えていました。サービス数が増えてきたので、terraformを触る人が増えてほしいなぁ、と。

当社においてマイクロサービス移行プロジェクトが目下進行中でした。そうです、マイクロサービス化した分だけ、クラウド上で管理するインフラも増えていくやつです。そこで、SRE部はボトルネックとならないよう、インフラをterraformコード化して、開発チームへ管理を委譲してきました。

しかし、terrformリポジトリが増えるにつれ、だんだんとCI/CDとtfstateの管理や、ワークフローの説明の負荷が増えてきます。かくして、
「Terraform Cloudを導入しよう! みんながもっと簡単に使えるように!」
というビッグウェーブは必然的に訪れ、PoCは幕明けたのでした。

要件

当社の業種は金融系ですので、原則としてしっかりとしたアクセス制御が求められます。

  • 開発と運用の職務分離
    サービスの開発をする人と、デプロイ・保守する人を分ける。
  • 最小権限の原則
    最低限必要なアクセス権限だけを付与する。

また、下記のような環境を前提に構成します。

  • クラウドはAzureを使用
  • Active DirectoryでSSO連携

つまり「開発と運用の職務分離」や「最小権限の原則」の要件を満たしつつ、Active DiretoryでSSO連携したTerraform Cloudから、Azureのリソースを構築したい、ということになります。

構成の検討

「開発と運用の職務分離」のため、開発チームと運用チームを設定するとします。開発チームは検証環境にのみアクセスでき、運用チームは検証および本番環境にアクセスできます。

想定できるTerraform Cloud構成としては、下記の2つから選択することになるかと思います。

  • 2つのorganizationを使って根本から分離
  • 1つのorganization内でチームの機能を使って分離

下記の表のようなことですね。

複数organization構成 単一organization構成
Organizations 開発チーム, 運用チーム -
Teams - 開発チーム, 運用チーム

複数organization構成だと、明確に分離できそうなので安心なのですが、一方で単一organization構成だと、下記のようにメリットが多いです。

  • 開発チームは本番環境のterraform planの結果を同一organization内で確認できる
  • Registry moduleが一箇所で済む
  • Organization毎に発生するライセンス料を節約できる

よって当社では、単一organization構成を選択しました。そして、チーム分けをしっかり運用するために、Terraform Cloudの設定をコード化し、そのためのCI/CD環境も構築していきます。

構成案

単一organization構成でチーム分けをする構成です。
terraform-cloud-teams.png

  • Active DirectoryでSSO連携します。
  • Active Directoryのgroupと、Terraform Cloud上のteamを対応させます。
  • Terraform Cloudのteamごとのアクセス制御をコード化し、Azure DevOpsにCI/CDパイプラインを構築します。

手順

Active DirectoryでSSO連携

Microsoft Azure AD - Single Sign-onを参考にSSO連携を構築します。

もし社内からのインターネットアクセスに、社内プロキシなどを使用している場合で、認証のうまく行かない時は、ドメインapp.terraform.ioを対象から外しましょう。

Active Directoryのgroupと、Terraform Cloud上のteamを対応させる

Active Directoryの設定

Microsoft Azure AD - Single Sign-onの「Team and Username Attributes」に項に説明があるものの、理解するのにActive Directoryの知識が前提として必要で難易度が高いです。ですので、下記に実際の構築手順を示します。

Enterprise Application › シングル サインオン › 属性とクレーム › 編集
「グループ要求を追加する」をクリックします。
image.png

「すべてのグループ」を選びます。
「グループ要求の名前をカスタマイズする」をチェックし、「名前」にMemberOfと入力し、「保存」をクリックします。
image.png

Terraform CloudでSSO team IDの設定

Active DirectoryのgroupのObject IDをメモしておきます。
Terraform Cloud › Organization Settings › Teams
「SSO team ID」にObject IDを入力して「Update team」ボタンを押します。
これをチームの数だけ繰り返し設定してください。

以上で、Active Directoryのgroupと、Terraform Cloud上のteamを対応させられたはずです。SSOでサインインして確認してみましょう。

Terraform Cloudのteamごとのアクセス制御をコード化

それでは、Azure DevOpsのPipelinesから、Terraform Cloudの設定を行えるようにしていきましょう。

VCS providerの追加

Azure DevOps Services - VCS Providers - Terraform Cloudを参考にVCS providerを追加します。

Azure DevOpsのApplicationの追加はProject Collection Administrator権限を持ったユーザで行ってください。そうしないと、追加したVCS providerにwebhookを作成する権限がなく、CI/CDからTerraform Cloudのworkspaceを作成できなくなります。

Terraform Cloudトークンを生成

API Tokens - Terraform Cloud を参考にして、管理体制に合うTerraform Cloudのトークンを生成し、Terraform CloudのCI/CDパイプラインから環境変数TFE_TOKENとして参照できる場所に格納します。(当社ではAzure Key Vaultに格納しています。)

VCS Providerを追加

Azure DevOps Services - VCS Providers - Terraform Cloudを参考にして、Azure用のterraformコードの置いてあるバージョン管理システムを登録します。

Azureの認証情報の設定

Terraform CloudのVariable Setsに、Azureリソースを操作するためのService Principalの認証情報を入れます。

ARM_SUBSCRIPTION_ID
ARM_TENANT_ID
ARM_CLIENT_ID
ARM_CLIENT_SECRET  # sensitive attributeとして追加

検証環境と本番環境とで、それぞれ定義します。

Terraform Cloudのteam, workspace, variable setsのアクセス制御をコーディング

TFE providerを参考にしつつ、アクセス制御をコーディングしましょう。

これでTerraform Cloudから、Azureのリソースを構築する準備が完了しました🎉

解説

なぜコード側ではなくActive Directoryによってチーム分けをするか

Terraform Cloudにおいて「organization membership IDが新しく振られてしまう問題」というものがありました。
例えばtfe_organization_membershipであらかじめユーザの所属状況を定義しておいたとします。その後、ユーザが初めてSSOサインインした際に、新しくID (organization membership ID) が振られてしまい、tfstateと不整合が生じてしまう、というものです。

つまり、あらかじめ「ユーザのチーム所属状態」を定義しておくことができず、下記のいずれかの回避策を講じる必要があります。

  • SSOサインインを待ってからCI/CDを走らせる
  • あるいは、新しく振られたIDをterraform importする

これだと運用の難易度が高くなってしまいますので、回避策として、terraformでユーザのチーム所属を定義するのを諦め、Active Directoryのgroup側で定義するようにしました。

Azure DevOps ApplicationをProject Collection Administratorで作成する際の注意点

Azure DevOps ApplicationをProject Collection Administratorの権限を持った人に作成してもらう必要があります。

Terraform CloudのAzure DevOps連携に、そのような強い権限を持つApplicationを接続することにリスクがあるものの、一方でworkspaceの作成をコード化しないと、管理者クラスの人が全てのworkspaceの作成を対応する必要があり、とても手間です。

よって、Terraform Cloudのコードレビューなどにより、間違いのあるコードの混入を防ぐ対策が必要です。

Terraform Cloudにプロジェクトという概念が欲しかった日々だった

Terraform Cloudの感触としては、下記の図のように「project(仮)」の概念を新たに導入して、workspaceやvariable setsのアクセス範囲を簡単に定義できたら良いな、と思いました。
terraform-cloud-project.png

今回は「開発チーム」と「運用チーム」に分離する例をとりあげましたが、その例で言うと「検証環境」と「本番環境」のprojectを作っておけば、teamとprojectの関係性を定義するだけで済み、Terraform Cloudの設定をさらにシンプルにできるはずです。

エンジニア募集中です!

bitFlyerでは、このようなワークフロー改善や、サービスの安定化および効率化のための業務を日々行うSREエンジニアの仲間を募集中です。ご興味を持たれた方、ぜひご応募ください!

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?