GAE へのデプロイが、支払い情報エラーで出来なかった時の備忘録

GCP (Google Cloud Platform) の GAE (Google App Engine) で、Web アプリをデプロイしようとしたら、エラーでデプロイができず、原因が支払い情報のエラーだと突き止めるまでにちょっと苦労したので備忘録。

## 前提
- GAE を利用している
- Google Cloud SDK がインストール済みである (gcloud コマンドが利用できる)
- デプロイ環境は Node.js (v12) ＝ ランタイムに `nodejs12` を指定
- Angular で開発した Web アプリをデプロイする

## 事象

Angular で生成した Web アプリを、GAE にデプロイしようとした。(過去に、全く同じ方法で、同一のソースコードをデプロイした実績がある)

ターミナルで「app.yaml」ファイルがあるディレクトリまで移動して、デプロイ コマンド実行したらこうなった。

```bash
# デプロイ実行
$ gcloud app deploy

(中略)

# コマンド実行する？ -> はい
Do you want to continue (Y/n)?  Y

# デプロイ処理スタート
Beginning deployment of service [default]...
╔════════════════════════════════════════════════════════════╗
╠═ Uploading 0 files to Google Cloud Storage                ═╣
╚════════════════════════════════════════════════════════════╝
File upload done. # ファイルアップロード完了
Updating service [default]...failed. # アップデートサービス失敗

# エラー発生
ERROR: (gcloud.app.deploy) Error Response: [9] Cloud build xxxxx-xxxx-xxxx-xxxx-xxxxx status: FAILURE.
Build error details: {"error":{"buildpackId":"","buildpackVersion":"","errorType":0,"canonicalCode":0,"errorId":"","errorMessage":""},"stats":[{"buildpackId":"google.nodejs.npm","buildpackVersion":"0.9.0","totalDurationMs":9739,"userDurationMs":8799},{"buildpackId":"google.nodejs.appengine","buildpackVersion":"0.9.0","totalDurationMs":1,"userDurationMs":0}]}.
Check the build log for errors: https://console.cloud.google.com/cloud-build/builds/xxxxx-xxxx-xxxx-xxxx-xxxxx?project=123456789
```

結果、エラーでデプロイ失敗

## エラー原因調査

うーん。コンソール表示のエラーでは、「`"errorId":"","errorMessage":""`」となっており、エラーIDもエラーメッセージも空文字なので、要因が全く検討もつかない...。
なんと不親切な。

ただ、URL が記載されているので、コンソールに表示されたエラーログ確認 URL にアクセスしてみる。

<img width="1440" alt="deploy_01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199602/3838f711-87b3-70ec-ff6a-62dc8f051a88.png">

うーん、さっぱりわからない。。。
わからないが、最下部のあたりに、更に URL を発見。

```
ERROR: failed to export: failed to write image to the following tags: [asia.gcr.io/xxxx-xxxx-xxxx/app-engine-tmp/build-cache/ttl-7d/default/buildpack-app:latest: PATCH https://asia.gcr.io/v2/xxxx-xxxx-xxxx/app-engine-tmp/build-cache/ttl-7d/default/buildpack-app/blobs/uploads/XXXX-xxx_XXX: DENIED: Access denied.]
```

「Access denied」とあるので、何らかの原因でアクセスが拒否されたようだ。
とりあえず、URL に飛んでみる。

<img width="803" alt="deploy_02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199602/ca44f15f-fc8d-7a3b-f8e0-f356201102f5.png">

表示されたのは、これだけ。
エラーコード：「`BLOB_UPLOAD_INVALID`」
エラーメッセージ「`An invalid blob upload was specified.`」（＝無効なBLOBアップロード処理が指定されました。）

これだけでは、何が何だかサッパリわからない。
インターネットで、エラーコードやエラーメッセージを検索してみても、日本語記事もないし、それっぽい記事も全くヒットしなかった。。。

### エラー要因を切り分けてみる

なぜ？つい最近までデプロイ出来ていたのに？

- app.yaml のファイルの書き方が間違っている？ → 違った。
- npm インストールの時に何か失敗した？ → 違った。
- npm ビルド処理で、デプロイするファイルが正しく生成されなかった？ → 違った。
- app.yaml のランタイムで指定する Node.js のバージョン値が非推奨になっている？ → 違った。
- Angular のバージョンが新しくなったりしたのが影響ある？ → 違った。

うーん、では試しに...

- 前回デプロイ成功しているソースコードがローカルに残っていたので、それをそのままもう一度デプロイできるか？ → できなかった。
- デプロイできるはずの、最低限の HTML ファイルと app.yaml の構成を用意して、それでデプロイできるか？ → できなかった。

### GCPの支払いに使っているクレジットカードの有効期限が切れていることに気づく

デプロイの処理や必要なファイルの状態に問題はなかった。
クレジットカード、そういえば先月末で有効期限が切れていた...。
もしかして、「アクセス拒否」っていうのは、支払い情報が無効になっているからだろうか...？

試しに、GCPのコンソールから、「Googleアカウント管理」へ行く。
通知アイコンから「カード支払いの情報が古い」旨のメッセージが着ている。

クレジットカードを、新しい有効な情報に修正し、支払い出来ていない決済を全て決済完了してみる。

### 支払い情報を正常にし、再度デプロイ実行

```bash
# デプロイ実行
$ gcloud app deploy

（中略）

# コマンド実行する？ -> はい
Do you want to continue (Y/n)?  Y

# デプロイ処理スタート
Beginning deployment of service [default]...
╔════════════════════════════════════════════════════════════╗
╠═ Uploading 0 files to Google Cloud Storage                ═╣
╚════════════════════════════════════════════════════════════╝
File upload done. # ファイルアップロード完了
Updating service [default]...done. # アップデートサービス成功
Setting traffic split for service [default]...done.
Deployed service [default] to [https://xxx-xxxx-xxx.appspot.com]

# デプロイ成功
You can stream logs from the command line by running:
  $ gcloud app logs tail -s default

To view your application in the web browser run:
  $ gcloud app browse
```

成功したっぽい。Webサイトにアクセスしてみたら、...うまくいきました。

## 原因

『GCP の支払い情報が無効なため、決済に失敗していたから。』
ただこれだけでした。

終わってみると大した理由ではなかったですが、意外とハマりそうなのでご注意を。