HashiCorp Vault 連携
HashiCorp Vault(英語) は、トークン、パスワード、証明書、暗号化キーを安全に保管するためのストレージです。 TeamCity パラメーターとトークン内に機密情報を保存する代わりに、Vault に保持し、Vault エンジン (KV/KV2、AWS、Google Cloud など) からこのデータに安全にアクセスできるように TeamCity を設定できます。
共通情報
HashiCorp Vault との統合を設定するには、次のものが必要です。
必要なプロジェクト内の HashiCorp Vault 接続 (任意の TeamCity プロジェクトでこの接続を使用する場合は <ルートプロジェクト>)。
必要なシークレットへの Vault パスを保存する パラメーター。
ビルドステップ (たとえば、
terraform apply -var password=%myVaultParam%行を実行する コマンドライン (スクリプト) ランナー) 内でのこのパラメーター (%parameter_name%) への参照。
このパラメーターを使用するビルドが開始されると、TeamCity サーバーは Vault 接続を使用してワンタイムの レスポンスラッピングトークン を要求し、それをこのビルドを実行する TeamCity エージェントに渡します。 ビルドエージェントはこのトークンを使用して Vault シークレットを要求し、取得した資格情報を TeamCity サーバーと共有することはありません。 ビルドが完了すると、エージェントのトークンは取り消されます。
Vault とのすべての通信は TeamCity サーバーによって調整されるため、この連携は拡張性が高く、Vault シークレットにアクセスするビルドエージェントの数の影響を受けません。 エージェントが TeamCity サーバーから受け取るトークンはリーストークン (Vault 接続のテストにのみ使用される) ではないため、実際のビルドエージェントの数はクォータに影響しません。 そのため、TeamCity サーバーに必要な Vault ライセンスは 1 つだけです。
Vault 接続を設定

プロジェクト設定を開き、 接続設定タブに移動します。
接続の追加をクリックします。 接続は親プロジェクトとサブプロジェクトでのみ使用できることに注意してください。 接続をグローバルに使用できるようにするには、 ルートプロジェクトに追加します。
接続タイプとして HashiCorp Vault を選択します。
基本的な接続設定(接続名、Vault URL と名前空間、オプションの ID)を指定します。
ボールトの名前空間(英語)を使用すると、「ボールト内にボールト」、つまり単一の Vault Enterprise インスタンス内に分離されたテナントを作成できます。 この分離環境に Vault シークレットを保存する場合は、 Vault 名前空間 接続フィールドにその名前空間を指定します (たとえば、
TeamABC/secrets/)。 それ以外の場合は、この設定を空のままにしておきます。識別子 は、この Vault 接続を識別するカスタム文字列です。 複数の Vault 接続を設定し、特定のパラメーターでどの接続を使用するかを指定する場合は、このフィールドを指定できます。 それ以外の場合は、このフィールドを空白のままにしておきます。
Vault URL は、Vault インスタンスのアドレスです。 ローカル Vault インストール (デフォルトの URL は
http://localhost:8200) もサポートされています。
必要な認証方法を選択します。 TeamCity は、Vault の AppRole、AWS IAM ロール、またはディレクトリアクセスプロトコル (LDAP) を使用して HCP Vault に認証できます。
この認証メソッドでは、Vault インスタンスで AppRole 認証メソッドを有効化し、 AppRole を作成する必要があります。 AppRole は、ユーザー (この場合は TeamCity) がアクセスできるシークレットを指定する Vault ポリシーのセットです。
Vault AppRole 認証メソッドでは、次の設定を行う必要があります:
AppRole 認証エンドポイントパス — AppRole 認証エンドポイントがマウントされている Vault インスタンス内のパス。 デフォルトのパスは
approle(前にバックスラッシュ文字は付きません) です。AppRole ロール ID と AppRole シークレット ID — これらの値は CLI で次のコマンドを使用して取得できます:
vault read -field=role_id auth/<AE>/role/<RN>/role-id vault write -f -field=secret_id auth/<AE>/role/<RN>/secret-id
ここで、<認証エンジン>は上で指定した認証エンドポイントパス (例:approle)、<ロール名>はロール名 (例:my-teamcity-role) です。
AppRoles オンラインドキュメント: ポリシー(英語)、 AppRole の認証方法(英語)の作成および設定方法については、Vault ドキュメントの記事を参照してください。
このメソッドは、 LDAP 認証メソッド が有効になっている Vault インスタンスで使用できます。 この認証オプションには、ユーザー名とパスワードが必要です。 パス 設定には、LDAP 認証エンドポイントへのパスが保存されます (たとえば、
ldapはデフォルトのauth/ldap/users/userAおよびauth/ldap/groups/groupBエンドポイント用です)。Vault でのこの認証方法の設定の詳細については、この記事を参照してください: LDAP 認証方式(英語)。
GCP IAM 認証 オプションを使用すると、TeamCity は Google Cloud 認証メソッドを使用してシークレットにアクセスできます。
Vault GCP ロール — 選択した GCP サービスアカウントの Vault アクセスロール。
$ vault write auth/gcp/role/role_name \ type="iam" \ policies="ACL_policy_name" \ bound_service_accounts="GCP_service_email_of_a_service_account>" \ max_jwt_exp="60m"GCP サービスアカウント ID —
Service Account Token Creator権限を持つ Google サービスアカウントの ID。 設定されていない場合は、 デフォルトの認証情報から値を取得します。GCP エンドポイントパス — Vault の認証方法名(デフォルトでは
gcp)。
接続のテストをクリックして、TeamCity がリソースにアクセスできることを確認し、新しい接続を保存します。
Kotlin DSL:
パラメーターを作成して設定
ビルドで HCP Vault のシークレット値の使用を開始するには、次の 2 つの目的を果たす パラメーターを作成します。
値を取得する必要がある Vault シークレットへのパスを保存します
Vault が提供した後にシークレット値を保存します
このようなパラメーターを作成するには、次の手順を実行します。
管理 | <プロジェクトまたはビルド構成> | パラメーター に移動し、 新しいパラメーターを追加 をクリックします。
環境変数 型を選択し、パラメーター名を入力します。 例:
env.AWS_ACCESS_KEY_ID。「仕様」ラベルの横にある 編集… をクリックし、次の値を設定します。
タイプ: リモート
リモート接続タイプ: HashiCorp ボールトパラメーター
パラメーターの名前空間: このパラメーターの値を取得するために使用する既存の ボールト接続を選択します。 このドロップダウンメニューには、ID を持つすべての接続の 表示名 が表示されます。


Vault クエリ:
パス!/鍵形式のシークレットへのパス。 例: 次の文字列は、パラメーターが KV2 エンジンに保存されている「awscreds」シークレットの「access_key」キーを指します:secret/data/awscreds!/access_key
ダイアログを閉じるには 保存 をクリックしてください。
Kotlin DSL:
既存パラメーターを更新
2023.11 バージョンより前に TeamCity Vault プラグインを使用していた場合、Vault シークレットへのパスをパラメーター値に直接保存するレガシーパラメーターがある可能性があります (%vault:PATH!/KEY% 形式)。
これらの従来のパラメーターと比較して、新しい「リモートパラメーター」には次の利点があります。
ボールトパスは Vault クエリ フィールドに保存され、 値 フィールドはデフォルト / 初期パラメーター値用に空けられます。
シークレットパス (クエリ) は、
vault:接頭辞のない、より単純な形式を使用します。
さらに、動的シークレットを発行する Vault エンジン (たとえば AWS エンジン) は、クライアント (TeamCity) が新しいリクエストを送信するたびに新しい資格情報を生成します。 そのため、同じビルド内で同じ動的シークレットエンジンにアクセスするレガシーパラメーターとリモートパラメーターを混合しないようにする必要があります。
たとえば、Vault AWS エンジンから Access Key ID を取得するリモートパラメーターと、対応する Secret Access Key を取得するレガシーパラメーターがある場合、TeamCity はパラメーターごとに個別のリクエストを送信します。 エンジンは 2 セットの値を発行するため、ID/ シークレットのペアは不一致になります。
既存のレガシーパラメーターをリモートの対応するパラメーターに更新することをお勧めします。
Kotlin DSL
Kotlin DSL では、従来の Vault パラメーターを新しい型に更新できます。 従来の Vault パラメーターは次のように宣言されます。
これらのパラメーターを更新するには、次のブロックに置き換えます。
元のパラメーター値とは異なり、新しいパラメーターの クエリ フィールドには vault: 接頭辞もパーセント文字も含まれないことに注意してください。
従来のパラメーターが %\vault:foobar:/パス!/鍵% 形式の場合、「foobar」部分は、このパラメーターがシークレットを取得するためにどの Vault 接続を使用するかを識別します。 この値をリモートパラメーターの vaultId フィールドに移動します。