Cloud Runで静的IPアドレスを設定するまでにやったこと

2024/03/19に公開

Expressを用いて簡単なWeb APIを実装し、Cloud Runで動かしていました。そのAPIからIPアドレスによるアクセス制限のかかった外部Web APIへのリクエストをする事になり、静的IPアドレスを付与することになりました。今回は静的IPアドレスを設定するまでにやったことを備忘録としてまとめます。

Cloud Runについて

APIとして簡単なものだったため、Cloud Functions for Firebaseで構築していましたが、アクセス量などを推測する中でCloud Runの方が良さそうに感じたため、Cloud Functions for Firebase (Gen2)によって構築しました。

サーバーレス VPC アクセス+Cloud NAT経由でインターネットにアクセス出来るようにする

Cloud Runはコンテナからインターネットにアクセスする際、動的IPアドレスプールを使用するようで、単体では静的IPアドレスを設定する事ができませんでした。

そこで調べていると、サーバーレスVPCを構築し、Cloud Runの前にCloud NATを用意することで静的IPアドレスを付与でき、そこを経由してインターネットにアクセスできるというものがありました。

参考にしたのは以下です。
https://blog.g-gen.co.jp/entry/cloudrun-using-static-ip
https://qiita.com/suzutatsu/items/8a54ba628e52c6be71aa

1つ目の記事に設定が細かく書かれているので詳細は省きますが、

  1. サーバーレス VPC アクセスコネクタを作成
  2. Cloud Routerを作成
  3. Cloud NATにCloud Routerを紐づけつつ静的IPアドレスを割り振る
  4. Cloud Runにアクセスコネクタを使用させる


Cloud Runの前にサーバーレスVPCとCloud NATを構築する

このような構成になります。

これで静的IPアドレスを指定してCloud Runに構築しているAPIにアクセス出来るようになります。

困ったところ

VPCコネクタがなかなか作成されない

確か2つ目の記事を参考に進めていましたが、VPCコネクタを作成するときのサブネットの指定が良くなかったようで、 /24 から /28 に変えつつ調整したらできました。(この辺りあまり得意じゃないな)

再デプロイをした際にVPCコネクタの指定が外れてしまう

firebase-toolsでのデプロイ時に実装側を参照されているようですが、 onRequest に指定ができていないのが原因でした。

import express from 'express';
import { onRequest } from "firebase-functions/v2/https";

const app = express();

// 中略

export const api = onRequest({
    region: "asia-northeast1",
    vpcConnector: 'VPC_CONNECTOR_NAME' // ここを追加
}, app);

便利だったサービス

構築した環境にちゃんと静的IPアドレスが振られているかの確認が必要になってきますが、http://checkip.dyndns.com が便利でした。

リクエストした際のIPアドレスを返してくれるため、検証用にExpressにエンドポイントを作りました。

import { Router, type Request, type Response } from "express";

const router = Router();

router.get("/check", async (_req: Request, res: Response) => {
  try {
    const response = await axios.get("http://checkip.dyndns.com/");
    return res.send(response.data);
  } catch (error) {
    console.error(error);
    return res.status(500).send("エラーが発生しました");
  }
});

やってみて

なかなかやる機会がない事だったので、最初はどうしようかと思いましたが、結果的にいい経験になりました。
Cloud Run自体は良さそうだったので、もっと早く触りたかった。

ファンタラクティブテックブログ

Discussion