サービスアカウントキーの作成が失敗。メッセージは「不明なエラーです」のみ

記事タイトルとURLをコピーする

G-gen の杉村です。ある Google Cloud 組織でサービスアカウントキーを発行しようとしたところ 不明なエラーです。 というメッセージと共に作成が失敗した事象が起きました。原因と対策を紹介します。

事象

サービスアカウントからサービスアカウントキー (秘密鍵) を生成しようとしたところ、以下のメッセージが出て作成できなかった。

`不明なエラーです。` `操作に失敗しました。もう一度お試しください。`

メッセージは 不明なエラーです。 操作に失敗しました。もう一度お試しください。 追跡番号 xxxxxxxxxxxxxxxx のみだ。

またコンソールだけでなく、gcloud コマンドでのキー生成を試みてもエラーとなる。

$ gcloud iam service-accounts keys create ./sa-key.json \
>    --iam-account=my-service-account@my-project.iam.gserviceaccount.com \
>    --project=my-project
ERROR: (gcloud.iam.service-accounts.keys.create) FAILED_PRECONDITION: Precondition check failed.

調査

サービスアカウントキー作成の失敗ログ

同プロジェクトの Cloud Logging をクエリすると、以下のログが出ている (一部を伏せ字・仮の値に置き換えている)。

サービスアカウントキーの作成が Precondition check failed. というメッセージ (“前提条件のチェックに失敗” の意味) と共にコード 9 で失敗していることが分かるが、それ以上は分からない。

{
  "protoPayload": {
    "@type": "type.googleapis.com/google.cloud.audit.AuditLog",
    "status": {
      "code": 9,
      "message": "Precondition check failed."
    },
    "authenticationInfo": {
      "principalEmail": "my-account@my-domain.com",
      "principalSubject": "user:my-account@my-domain.com"
    },
    "requestMetadata": {
      "callerIp": "x.x.x.x",
      "callerSuppliedUserAgent": "Mozilla/5.0 (X11; CrOS x86_64 15183.59.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36,gzip(gfe)",
      "requestAttributes": {
        "time": "2022-12-14T08:42:34.568951085Z",
        "auth": {}
      },
      "destinationAttributes": {}
    },
    "serviceName": "iam.googleapis.com",
    "methodName": "google.iam.admin.v1.CreateServiceAccountKey",
    "authorizationInfo": [
      {
        "resource": "projects/-/serviceAccounts/123456789012345678901",
        "permission": "iam.serviceAccountKeys.create",
        "granted": true,
        "resourceAttributes": {
          "name": "projects/-/serviceAccounts/123456789012345678901"
        }
      }
    ],
    "resourceName": "projects/-/serviceAccounts/123456789012345678901",
    "request": {
      "private_key_type": 2,
      "@type": "type.googleapis.com/google.iam.admin.v1.CreateServiceAccountKeyRequest",
      "name": "projects/my-project/serviceAccounts/123456789012345678901"
    },
    "response": {
      "@type": "type.googleapis.com/google.iam.admin.v1.ServiceAccountKey"
    }
  },
  "insertId": "abcd123456789",
  "resource": {
    "type": "service_account",
    "labels": {
      "email_id": "my-service-account@my-project.iam.gserviceaccount.com",
      "project_id": "my-project",
      "unique_id": "123456789012345678901"
    }
  },
  "timestamp": "2022-12-14T08:42:34.548887889Z",
  "severity": "ERROR",
  "logName": "projects/my-project/logs/cloudaudit.googleapis.com%2Factivity",
  "receiveTimestamp": "2022-12-14T08:42:36.473110470Z"
}

同時刻のログに解決の糸口

しかし、上記ログとほぼ同タイミングで、以下のようなログが出力されていた。ほぼ同時刻であるためコンソールの Cloud Logging のログエクスプローラーで隣り合った位置に出力されており、特にクエリでログを絞っていなかったため気がつくことができた。

{
  "protoPayload": {
    "@type": "type.googleapis.com/google.cloud.audit.AuditLog",
    "status": {
      "code": 7,
      "message": "PERMISSION_DENIED"
    },
    "authenticationInfo": {},
    "requestMetadata": {
      "callerIp": "private",
      "requestAttributes": {},
      "destinationAttributes": {}
    },
    "serviceName": "resourcesettings.googleapis.com",
    "methodName": "google.cloud.resourcesettings.v1alpha1.ResourceSettingsService.LookupEffectiveSettingValue",
    "resourceName": "projects/123456789012",
    "metadata": {
      "@type": "type.googleapis.com/google.cloud.audit.OrgPolicyRestrictionAuditMetadata",
      "violationReason": "SERVICE_USAGE_RESTRICTION_VIOLATED",
      "resourceNames": [
        "projects/123456789012/settings/iam-serviceAccountKeyExpiry"
      ]
    },
    "policyViolationInfo": {
      "orgPolicyViolationInfo": {
        "violationInfo": [
          {
            "constraint": "constraints/gcp.restrictServiceUsage",
            "errorMessage": "Resource Usage Restriction Org Policy is violated",
            "policyType": "LIST_CONSTRAINT"
          }
        ]
      }
    }
  },
  "insertId": "123456789abc",
  "resource": {
    "type": "audited_resource",
    "labels": {
      "project_id": "my-project",
      "service": "resourcesettings.googleapis.com",
      "method": "google.cloud.resourcesettings.v1alpha1.ResourceSettingsService.LookupEffectiveSettingValue"
    }
  },
  "timestamp": "2022-12-14T08:42:34.705300886Z",
  "severity": "ERROR",
  "logName": "projects/my-project/logs/cloudaudit.googleapis.com%2Fpolicy",
  "receiveTimestamp": "2022-12-14T08:42:35.286107268Z"
}

これは、組織のポリシー constraints/gcp.restrictServiceUsage の制限によって API resourcesettings.googleapis.com が拒否されたことを示すログだ。

確かに、今回事象が起きた Google Cloud 組織では 組織のポリシー constraints/gcp.restrictServiceUsage (利用可能な Google Cloud サービスを制限するポリシー) を使って、環境利用者が特定の Google Cloud サービスしか使えないように制限をかけていた。このポリシーが、原因に関係しそうだ。

二種類のログがセットで出力されていたことに気がついた

原因と対処

対処法を先に書くと、組織ポリシー constraints/gcp.restrictServiceUsage の許可リストに resourcesettings.googleapis.com を追加すると、事象は解決した。

Resource Settings API は Google Cloud リソースの振る舞いを管理する API であり、VM、VPC Firewall、プロジェクトなど様々なリソースの管理のため、バックエンドで用いられている。

また、我々ユーザーも同 API を利用することにより、リソース作成時のデフォルトのロケーションを設定するなど、組織で一貫した設定値を管理することができる。

今回の事象の原因は、組織ポリシー constraints/gcp.restrictServiceUsage によってバックエンドで用いられている Resource Settings API が禁止されてしまっていたためだった。そのため同 API を示す resourcesettings.googleapis.com を許可リストに追加することで、事象が解決した。

ほとんどの場合で Google Cloud API は適切なエラーログを出力するため、トラブルに遭遇したらまずを Cloud Logging を精査するのが得策だ。

杉村 勇馬 (記事一覧)

執行役員 CTO / クラウドソリューション部 部長

元警察官という経歴を持つ現 IT エンジニア。クラウド管理・運用やネットワークに知見。AWS 12資格、Google Cloud認定資格11資格。X (旧 Twitter) では Google Cloud や AWS のアップデート情報をつぶやいています。