IAM 認証を管理する

このページでは、Memorystore クラスタの IAM 認証機能の一般的なタスクに関する手順について説明します。この機能の詳細については、IAM 認証についてをご覧ください。

IAM 認証を使用するクラスタを作成する

IAM 認証を使用するクラスタを作成するには、create コマンドを実行します。

gcloud alpha redis clusters create INSTANCE_ID --region=REGION_ID --size-gb=SIZE --auth-mode=AUTH_MODE_IAM_AUTH

以下を置き換えます。

  • INSTANCE_ID は、作成する Memorystore Cluster for Redis インスタンスの ID です。インスタンス ID は 1〜63 文字にする必要があり、小文字、数字、ハイフンのみ使用できます。先頭は英小文字に、末尾は英小文字または数字にする必要があります。

  • REGION_ID は、インスタンスを配置するリージョンです。

  • SIZE は、インスタンスに必要なサイズ(GB)です。この値の範囲は 12~336 であり、4 で割り切れる必要があります。デフォルト値は 12 です。

IAM 認証の権限を管理する

Memorystore クラスタに対して制限付き IAM 管理者ロールを作成する

完全な IAM 管理者権限を付与せずに、Memorystore クラスタ接続の IAM 権限を変更できるロールを作成することもできます。これを行うには、「roles/redis.dbConnectionUser」ロールに対して制限付き IAM 管理者を作成します。詳しくは、制限付き IAM 管理者を作成するをご覧ください。

IAM でクラスタへのアクセス権を付与する

デフォルトでは、プリンシパルに roles/redis.dbConnectionUser ロールを付与すると、プリンシパルはプロジェクト内のすべてのクラスタにアクセスできます。プロジェクト内のリソースのサブセットへのアクセス権を付与するには、roles/redis.dbConnectionUser ロールの IAM リソースベースのアクセス権を設定します。詳しくは、リソースベースのアクセスを構成するをご覧ください。

IAM 認証を使用するクラスタへの接続

  1. プロジェクトで Redis インスタンスのPrivate Service Connect アタッチメントを構成します(まだ構成していない場合)。

  2. Redis クラスタと同じ承認済みネットワークを使用する Compute Engine VM がまだない場合は、作成してから、Linux VM の使用に関するクイックスタートに沿って接続します。

  3. Compute Engine SSH ターミナルから次のコマンドを実行して、redis-cli を Compute Engine VM にインストールします。

    sudo apt-get install redis-tools
    
  4. 次のコマンドを実行して、IAM ユーザーのアクセス トークンを取得します。

    gcloud auth print-access-token
    
  5. 次のコマンドを実行し、redis-cli を使用して認証を行い、インスタンスに接続します。変数は適切な値に置き換えます。

    redis-cli -h PRIVATE_SERVICE_CONNECT_ENDPOINT_IP -a ACCESS_TOKEN
    

    または

    redis-cli -h PRIVATE_SERVICE_CONNECT_ENDPOINT_IP
    AUTH ACCESS_TOKEN
    

    以下を置き換えます。

  6. Redis の SETGET のコマンドを実行して、インスタンスに対する認証済み接続が確立されたことを確認します。

  7. Redis クラスタへの接続をテストしたら、Redis クラスタへの接続に使用した Compute Engine VM を削除することを検討してください。そうすることで、Cloud 請求先アカウントへの課金を回避できます。

アクセス トークンの取得を自動化する

アクセス トークンの有効期限は短いため、アクセス トークンは簡単にハードコードできません。そのため、アプリケーションでアクセス トークンの取得を自動化することをおすすめします。

  1. アプリケーションのサービス アカウントを作成します(サービス アカウントの作成と管理を参照してください)。

    gcloud iam service-accounts create SA_NAME \
        --description="DESCRIPTION" \
        --display-name="DISPLAY_NAME"
    

    以下を置き換えます。

    • SA_NAME はサービス アカウントの名前です。
    • DESCRIPTION は、サービス アカウントの説明です(省略可能)。
    • DISPLAY_NAME は、Google Cloud コンソールに表示するサービス アカウント名です。
  2. サービス アカウントにプロジェクトに対する redis.dbConnectionUser 権限を付与します。

    gcloud projects add-iam-policy-binding PROJECT_ID \
    --member="serviceAccount:SA_NAME@PROJECT_ID.iam.gserviceaccount.com" \
    --role="redis.dbConnectionUser"
    

    以下を置き換えます。

    • PROJECT_ID は、プロジェクト ID です。
    • SA_NAME はサービス アカウントの名前です。
    • ROLE_NAME はロール名です(例: roles/compute.osLogin)。
  3. 指定されたサービス アカウントとしてアプリケーションを認証します。詳細については、サービス アカウントをご覧ください。

    一般的なクライアント ライブラリを使用してアプリケーションを認証する方法を示すコードサンプルについては、IAM 認証クライアント ライブラリのコードサンプルをご覧ください。

IAM 認証クライアント ライブラリのコードサンプル

このセクションでは、redis-py クライアント ライブラリを使用して Memorystore クラスタの IAM 認証で認証するためのクライアント コードの一般的な例を示します。

redis-py

def generate_access_token():
  # Create a client
  client = iam_credentials_v1.IAMCredentialsClient()

  # Initialize request argument(s)
  request = iam_credentials_v1.GenerateAccessTokenRequest(
     name="projects/-/serviceAccounts/example-service-account@example-project.iam.gserviceaccount.com",
     scope=['https://www.googleapis.com/auth/cloud-platform'],
  )

  # Make the request
  response = client.generate_access_token(request=request)

  # Handle the response
  return str(response.access_token)

def iam_connect(self):
  "Initialize the connection, authenticate and select a database"
  self._parser.on_connect(self)

  auth_args = (generate_access_token(),)
  # avoid checking health here -- PING will fail if we try
  # to check the health prior to the AUTH
  self.send_command("AUTH", *auth_args, check_health=False)

  try:
     auth_response = self.read_response()
  except AuthenticationWrongNumberOfArgsError:
     # a username and password were specified but the Redis
     # server seems to be < 6.0.0 which expects a single password
     # arg. retry auth with just the password.
     # https://github.com/andymccurdy/redis-py/issues/1274
     self.send_command("AUTH", self.password, check_health=False)
     auth_response = self.read_response()

  if str_if_bytes(auth_response) != "OK":
     raise AuthenticationError("Invalid Username or Password")

  # if a client_name is given, set it
  if self.client_name:
     self.send_command("CLIENT", "SETNAME", self.client_name)
     if str_if_bytes(self.read_response()) != "OK":
           raise ConnectionError("Error setting client name")

  # if a database is specified, switch to it
  if self.db:
     self.send_command("SELECT", self.db)
     if str_if_bytes(self.read_response()) != "OK":
           raise ConnectionError("Invalid Database")

backoff = ConstantBackoff(3)
retry = Retry(retries=-1, backoff=backoff, supported_errors=(ConnectionError, ConnectionResetError))
r=redis.Redis(host='localhost', port=6000,redis_connect_func=iam_connect, retry=retry)
start = time.time()
while(1):
  time.sleep(5)
  print(r.get('key'))
  end = time.time()
  print (end-start)