IAM の条件を使用する

IAM Conditions を使用すると、Cloud SQL インスタンスを含む Google Cloud リソースに属性ベースの条件付きアクセス制御を定義して、適用できます。IAM Conditions の詳細については、IAM Conditions の概要をご覧ください。

はじめに

Cloud SQL では、次の属性に基づいて条件付きアクセスを適用できます。

  • 日時属性: Cloud SQL リソースに対する一時的な(有効期限のある)アクセス権、スケジュール済みアクセス権、または期間限定のアクセス権を設定するために使用します。たとえば、指定した日付までの間、ユーザーはデータベース インスタンスにアクセスできます。日時属性は、リソース階層の任意のレベルで使用できます。詳細については、一時アクセスの構成をご覧ください。
  • リソース属性: タグ、リソース名、リソースタイプ、リソース サービス属性に基づいて条件付きアクセスを構成するために使用します。Cloud SQL では、データベース インスタンスの属性を使用して条件付きアクセスを構成できます。たとえば、特定のタグを持つインスタンスに対するアクセスのみをユーザーに許可できます。詳細については、リソースベースのアクセスの構成をご覧ください。

次のような用途があります。

  • ユーザーに特定のインスタンスへの接続を許可する。

  • ユーザーに特定の接頭辞または接尾辞(test など)を持つインスタンスの作成を許可する。

  • テスト インスタンスのバックアップ オペレーションへのアクセスを制限する。

  • ユーザーに開発インスタンスとテスト インスタンスの削除を許可するが、本番環境インスタンスの削除は許可しない。

  • ユーザーが特定の日付または時刻に管理オペレーションを実行できるようにする。

ユーザーに特定のインスタンスへの接続を許可する

ユーザーまたはサービス アカウントに、特定の Cloud SQL インスタンスにのみ接続を許可するとします。この場合、Cloud SQL ロールの権限を付与する IAM Condition を IAM ポリシー バインディングに含めることができます。

デフォルトでは、Cloud SQL クライアントの事前定義ロール(roles/cloudsql.client)には、cloudsql.instances.connect 権限が含まれおり、そのメンバーにはプロジェクトのすべての Cloud SQL インスタンスへの接続が認可されます。IAM Condition をポリシー バインディングに含めることで、指定したインスタンスのみに対する権限を付与できます。

コンソール

この例では、プロジェクトの既存の IAM バインディングを変更して、サービス アカウントに特定のインスタンスに対する Cloud SQL クライアントのロールを付与する方法を示します。

この例では、次の変数を使用します。

  • PROJECT_ID: Google Cloud プロジェクト。
  • INSTANCE_ID: アクセスを許可するインスタンスの名前。

  1. Google Cloud コンソールの [IAM] ページに移動します。

    [IAM] に移動

  2. [追加] をクリックします。
  3. [新しいメンバー] 入力ボックスに、サービス アカウントのメールアドレスを入力します。
  4. [ロール] プルダウン リストをクリックし、[Cloud SQL クライアント] ロールを選択します。
  5. [条件を追加] をクリックします。
  6. タイトルと説明を入力します。
  7. [条件エディタ] タブを選択します。
  8. [条件ビルダー] セクションで、次の操作を行います。
    • [条件タイプ] > [リソース] > [名前] の順に選択し、「projects/PROJECT_ID/instances/INSTANCE_ID」と入力します。
    • [AND] 条件が選択されていることを確認します。
    • [条件タイプ] > [リソース] > [サービス] の順に選択し、[sqladmin.googleapis.com] を選択します。
  9. [保存] をクリックして、条件を保存します。
  10. [保存] をクリックして、ポリシーを保存します。

gcloud

この例では、プロジェクトの既存の IAM ポリシー バインディングを変更して、特定のサービス アカウントに Cloud SQL クライアントのロールを付与する方法を示しますが、特定のインスタンスのみを対象としています。

この例では、次の変数を使用します。

  • PROJECT_ID: Google Cloud プロジェクト。
  • INSTANCE_ID: アクセスを許可するインスタンスの名前。
  • SERVICE_ACCOUNT_EMAIL: アクセス権を変更するサービス アカウントの完全なメールアドレス。

  1. 既存の IAM ポリシー バインディングを取得し、bindings.json ファイルに出力します。
  2. gcloud projects get-iam-policy PROJECT_ID --format=json > bindings.json
    
  3. 次の条件付きロール バインディングを bindings.json ファイルに追加します。
    {
      "bindings": [
        {
          "role": "roles/cloudsql.client",
          "members": [
            "serviceAccount:SERVICE_ACCOUNT_EMAIL"
          ],
          "condition": {
            "expression": "resource.name == 'projects/PROJECT_ID/instances/INSTANCE_ID'
              && resource.service == 'sqladmin.googleapis.com'"
          }
        }
      ],
      "etag": "BwWKmjvelug=",
      "version": 3
    }
    
  4. 新しい bindings.json ファイルを使用して IAM ポリシーを更新します。
    gcloud projects set-iam-policy PROJECT_ID bindings.json
    

Terraform

ユーザーが特定のインスタンスに接続できるようにするには、Terraform google_iam_policy データリソースgoogle_project_iam_policy Terraform リソースを使用します。

data "google_iam_policy" "sql_iam_policy" {
  binding {
    role = "roles/cloudsql.client"
    members = [
      "serviceAccount:${google_project_service_identity.gcp_sa_cloud_sql.email}",
    ]
    condition {
      expression  = "resource.name == 'projects/${data.google_project.project.project_id}/instances/${google_sql_database_instance.default.name}' && resource.type == 'sqladmin.googleapis.com/Instance'"
      title       = "created"
      description = "Cloud SQL instance creation"
    }
  }
}

resource "google_project_iam_policy" "project" {
  project     = data.google_project.project.project_id
  policy_data = data.google_iam_policy.sql_iam_policy.policy_data
}

変更を適用する

Google Cloud プロジェクトで Terraform 構成を適用するには、次のセクションの手順を完了します。

Cloud Shell を準備する

  1. Cloud Shell を起動します。
  2. Terraform 構成を適用するデフォルトの Google Cloud プロジェクトを設定します。

    このコマンドは、プロジェクトごとに 1 回だけ実行する必要があります。これは任意のディレクトリで実行できます。

    export GOOGLE_CLOUD_PROJECT=PROJECT_ID

    Terraform 構成ファイルに明示的な値を設定すると、環境変数がオーバーライドされます。

ディレクトリを準備する

Terraform 構成ファイルには独自のディレクトリ(ルート モジュールとも呼ばれます)が必要です。

  1. Cloud Shell で、ディレクトリを作成し、そのディレクトリ内に新しいファイルを作成します。ファイルの拡張子は .tf にする必要があります(例: main.tf)。このチュートリアルでは、このファイルを main.tf とします。
    mkdir DIRECTORY && cd DIRECTORY && touch main.tf
  2. チュートリアルを使用している場合は、各セクションまたはステップのサンプルコードをコピーできます。

    新しく作成した main.tf にサンプルコードをコピーします。

    必要に応じて、GitHub からコードをコピーします。Terraform スニペットがエンドツーエンドのソリューションの一部である場合は、この方法をおすすめします。

  3. 環境に適用するサンプル パラメータを確認し、変更します。
  4. 変更を保存します。
  5. Terraform を初期化します。これは、ディレクトリごとに 1 回だけ行います。
    terraform init

    最新バージョンの Google プロバイダを使用する場合は、-upgrade オプションを使用します。

    terraform init -upgrade

変更を適用する

  1. 構成を確認して、Terraform が作成または更新するリソースが想定どおりであることを確認します。
    terraform plan

    必要に応じて構成を修正します。

  2. 次のコマンドを実行します。プロンプトで「yes」と入力して、Terraform 構成を適用します。
    terraform apply

    Terraform に「Apply complete!」というメッセージが表示されるまで待ちます。

  3. Google Cloud プロジェクトを開いて結果を表示します。Google Cloud コンソールの UI でリソースに移動して、Terraform によって作成または更新されたことを確認します。

変更を削除する

変更を削除するには、次の手順を行います。

  1. 削除の保護を無効にするには、Terraform 構成ファイルで deletion_protection 引数を false に設定します。
    deletion_protection =  "false"
  2. 次のコマンドを実行します。プロンプトで「yes」と入力して、更新された Terraform 構成を適用します。
    terraform apply
  1. 次のコマンドを実行しています。プロンプトで「yes」と入力して、以前に Terraform 構成で適用されたリソースを削除します。

    terraform destroy

テスト インスタンスのバックアップ オペレーションへのアクセスを制限する

すべてのテスト インスタンスの接頭辞が test(例: test-instance-1)で、すべての本番環境インスタンスの接頭辞が prod(例: prod-instance-1)になるようにサービスのトポロジが構成されているとします。

バックアップ オペレーションへのアクセスは、ユーザーまたはサービス アカウントのテスト インスタンスに限定できます。アクセスを制限すると、テスト インスタンスのバックアップに対する CREATEGETLISTDELETE オペレーションを制限できます。

コンソール

  1. Google Cloud コンソールの [IAM] ページに移動します。

    [IAM] に移動

  2. [プリンシパル] タブをクリックします。
  3. アクセスを制限するユーザーのメールアドレスまたはサービス アカウント(プリンシパル)を見つけます。
  4. プリンシパルの右側にある「プリンシパルを編集します」アイコンをクリックします。このアイコンは鉛筆として表示されます。
  5. [権限の編集] ダイアログ ボックスで、[別のロールを追加] をクリックします。
  6. 次のダイアログ ボックスの [フィルタ] フィールドに「Cloud SQL Admin」と入力します。表示された [Cloud SQL 管理者] ロールを選択します。

    [権限の編集] ダイアログ ボックスがアクティブになり、ダイアログ ボックスに [Cloud SQL 管理者] ロールが表示されます。

  7. [Cloud SQL 管理者] ロールの右側にある [条件を追加] をクリックします。
  8. [条件の編集] ダイアログ ボックスで、次の情報を入力します。
    1. [タイトル] フィールドに、テスト インスタンスのバックアップ オペレーションへのアクセスを制限する条件の名前を入力します。たとえば、「Limit access to backup operations」と入力します。
    2. [条件エディタ] タブをクリックして、次の条件を追加します。

      resource.type == "sqladmin.googleapis.com/BackupRun" &&
      resource.name.startsWith("projects/PROJECT_ID/instances/test")
          

  9. [保存] をクリックします。
  10. [権限の編集] ダイアログ ボックスで、[保存] をクリックします。

gcloud

この例では、次の変数を使用します。

  • PROJECT_ID: Google Cloud プロジェクト。
  • USER_EMAIL: ユーザーのメールアドレス。
  • SERVICE_ACCOUNT_EMAIL: アクセスを制限するサービス アカウントの完全なメールアドレス。

  1. メールアドレスが USER_EMAIL のユーザーの cloudsql.admin ロールのスコープを制限します。

    ロールのスコープは、projects/PROJECT_ID/instances/test で始まるリソース名のリソースに限定されます。

    gcloud projects add-iam-policy-binding PROJECT_ID \ --member=user:USER_EMAIL \
    --role=roles/cloudsql.admin \
    --condition=expression="resource.type == \"sqladmin.googleapis.com/BackupRun\" && resource.name.startsWith(\"projects/PROJECT_ID/instances/test-instance-1\")",title="test"
        
  2. または

  3. サービス アカウント SERVICE_ACCOUNT_EMAIL でログインしているユーザーの cloudsql.admin ロールのスコープを制限します。

    gcloud projects add-iam-policy-binding PROJECT_ID \ --member=serviceAccount:SERVICE_ACCOUNT_EMAIL \
    --role=roles/cloudsql.admin \
    --condition=expression="resource.type == \"sqladmin.googleapis.com/BackupRun\" && resource.name.startsWith(\"projects/PROJECT_ID/instances/test-instance-1\")",title="test"
        

ユーザーにテスト インスタンスの削除を許可する(本番環境インスタンスの削除は許可しない)

サービス アカウントにテスト インスタンスの削除を許可し、本番環境インスタンスの削除は許可しない場合について考えてみましょう。これを行うには、タグを使用して、サービス アカウントに次の 2 つのポリシー バインディングを追加します。

  • ロールを付与したリソースとその子孫に対する Cloud SQL 編集者のロール。プロジェクトにロールを付与すると、プロジェクト内のすべてのインスタンスにロールが適用されます。Cloud SQL 編集者のロールに cloudsql.instances.delete 権限は含まれていません。
  • test タグを持つインスタンスに対する Cloud SQL 管理者のロール。

コンソール

  1. Google Cloud コンソールの [IAM] ページに移動します。

    [IAM] に移動

  2. [追加] をクリックします。
  3. [新しいメンバー] フィールドに、サービス アカウントのメールアドレスを入力します。
  4. [ロール] プルダウン リストをクリックし、[Cloud SQL 編集者] 選択します。このロールにはこれ以上何も追加しません。
  5. [保存] をクリックして、条件を保存します。
  6. 同じアカウントの [ロール] メニューをクリックし、[Cloud SQL 管理者] を選択します。
  7. [条件を追加] をクリックします。
  8. タイトルと説明を入力します。
  9. [条件エディタ] タブを選択します。
  10. [条件ビルダー] セクションで、次の操作を行います。
    • [条件タイプ] > [リソース] > [名前] の順に選択し、条件の名前を入力します。
    • [条件タイプ] > [リソース] > [サービス] の順に選択し、[sqladmin.googleapis.com] を選択します。
    • [条件タイプ] > [リソース] > [サービス] の順に移動し、タグキーの名前空間名を入力します。この例では、[Operator] は matches で、値は 815471563813/env/test です。
  11. [保存] をクリックして、条件を保存します。
  12. [保存] をクリックして、ポリシーを保存します。

gcloud

この例では、次の変数を使用します。

  • PROJECT_ID: Google Cloud プロジェクト。
  • INSTANCE_ID: Cloud SQL インスタンス。
  • REGION: Cloud SQL インスタンスが配置されているリージョン。
  • ORGANIZATION_ID: このタグキーの親リソースの組織 ID(例: 12345678901)。組織 ID を取得する方法については、組織の作成と管理をご覧ください。
  • SERVICE_ACCOUNT_EMAIL: アクセス権を変更するサービス アカウントの完全なメールアドレス。

  1. タグ値が「prod」と「test」で、名前が「env」のタグキーを作成します。詳しくは、新しいタグの作成と定義をご覧ください。
    gcloud alpha resource-manager tags keys create env \
    --parent=organizations/ORGANIZATION_ID
    gcloud alpha resource-manager tags values create prod \
    --parent=env
    gcloud alpha resource-manager tags values create test \
    --parent=env
        
  2. テスト環境の Cloud SQL インスタンスに、値「test」が指定された「env」タグを適用します。詳細については、Cloud SQL タグのページをご覧ください。
  3. gcloud alpha resource-manager tags bindings create \
    --tag-value=test \
    --parent=//sqladmin.googleapis.com/projects/PROJECT_ID/instances/INSTANCE_ID \
    --location=REGION
      
  4. 既存の IAM ポリシー バインディングを取得し、bindings.json ファイルに出力します。
    gcloud projects get-iam-policy PROJECT_ID --format=json >> bindings.json
    
  5. 次の条件付きバインディングを bindings.json ファイルに追加します。
    {
      "bindings": [
        {
          "role": "roles/cloudsql.editor",
          "members": [
              "serviceAccount:SERVICE_ACCOUNT_EMAIL"
            ]
        },
        {
          "role": "roles/cloudsql.admin",
          "members": [
              "serviceAccount:SERVICE_ACCOUNT_EMAIL"
            ],
          "condition": {
            "expression": "resource.matchTag('ORGANIZATION_ID/env', 'test')"
          }
        }
      ],
      "etag": "BwWKmjvelug="
      "version": 3
    }
    
  6. 新しい bindings.json ファイルを使用して IAM ポリシー バインディングを更新します。
    gcloud projects set-iam-policy PROJECT_ID bindings.json