AWSエンジニアがGCPでハマりがちなポイント

![AWSエンジニアがGCPでハマりがちなポイント.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/852059/cd2b0be5-792a-3a71-2097-1bfa654d0cf5.png)

Japan Digital Design（以下JDD）でインフラエンジニアをしている渡邉です。
[Japan Digital Design Advent Calendar 2023](https://adventar.org/calendars/9000) もついに19日目までやってまいりました。
後半だしまだ全然余裕～、とのんびりしていたら、あっと言う間にやってきました...。

https://adventar.org/calendars/9000


さて、今回は Google Cloud Platform（以下GCP）に関するお話です。
JDDでは各プロジェクトそれぞれでインフラ選定が異なりますが、基本的にはAWSをメインで利用しています。
GCPはPoCや内部的なアプリケーションに利用が限られていたわけですが、ついにProductionサービスでの利用が決まり、GCPを本格的に使うことになりました。

AWSにどっぷり浸かったインフラエンジニアがGCPを使い始めるにあたって、きっとハマるであろうポイントをいくつか挙げてみようと思います。

## こんな人向け
AWSは結構使ってきたけど、GCPよく分かない

## リソース管理単位
### Account (AWS)　vs　Project (GCP)
AWSがOrganizationから用途ごとにアカウントを発行します。
それに対してGCPの場合は、Google Workspace（Cloud Identity）に紐づけた1つのGCP環境の中に、`Organization` および `Project` というものがまとめて存在します。
OUに関してもGCPでは `Folder` という名称（機能）になっています。

#### AWS
```
Organization (in Management Account)
  ∟ OU
    ∟ Account 1
    ∟ Account 2
```
#### GCP
```
Google Workspace
  ∟ Organization
      ∟ Folder
        ∟ Project 1
        ∟ Project 2
```


## IAM

### 継承
何と言っても一番の違いはこれではないでしょうか。
AWSの場合、各アカウント毎にIAMを管理しており、アカウントを超えてアクセスを行う場合は、そのためにポリシーを調整する必要があります。（Control Tower の場合はその辺勝手に入ったりしますが、あくまで裏でよしなにしてくれているだけ）
デフォルトではアカウントを跨ぐことは出来ません。

GCPの場合、上位リソースで定義したIAMの権限は、その配下のリソース（Folder、Project）に継承されます。

#### AWS
```
Organization (in Management Account)  ←このアカウントでAさんにAdministratorAccessを付与
  ∟ OU
    ∟ Account 1 ← Aさん：アクセス不可
    ∟ Account 2 ← Aさん：アクセス不可
```

#### GCP
```
Google Workspace
  ∟ Organization　    ←ここでAさんにroles/ownerを付与
      ∟ Folder        ← Aさん:roles/owner
        ∟ Project 1   ← Aさん:roles/owner
        ∟ Project 2   ← Aさん:roles/owner
```


一見便利そうに見えますが、Production 向けのアーキテクチャや権限設計をするにあたって、厳密に権限分掌をする必要が出てくると若干困りごとが出てきます。
権限を Organization など上位で与えてしまうと「見せてはいけないものが見える」状況になる可能性があります。

継承を切るということができないため、Organization や上位 Folder レベルでの権限付与は最低限にする必要がありますが、Organization レベルでしか付与できないロールもあり、設計時は後述するロールやポリシーのドキュメントとにらめっこし、場合によっては拒否ポリシーや後述の VPC Service Control を検討することになります。

### Role & Permission
ロールはAWSと同じかな？と思いきや、GCPのロールはAWSでいうところのマネージドポリシーに近いです。同じように、GCPのPermissionはAWSのポリシー内Actionといった感じです。

また、AWSに慣れた脳だと「IAM Policyはどこで書けば？」となりがちですが、GCPの場合、リソースに対して権限付与を行います。いわゆるリソースベースポリシーだけがあるようなイメージです。（Project,Folder,Organizationもリソース扱い）

GCPのマネージドロールの数は膨大です
ロールや権限で悩んだときに良く利用するドキュメントは下記2つです。

#### 権限（Permission）から必要なロールを逆引きする場合

https://cloud.google.com/iam/docs/permissions-reference

#### 全てのロールの権限を見たい場合

https://cloud.google.com/iam/docs/understanding-roles

なお、基本ロールと呼ばれるOwner, Editor, Viewerの権限は上記のロール一覧には記載がありません（おそらく多すぎるので書かれてない）。
基本ロールはGCPコンソールのIAMロールページで確認できます。
ドキュメントが怪しい場合もコンソールで確認する方が確実です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/852059/3368019a-c32c-cddd-d018-1ea37cf0265d.png)

なお、GCPの場合、カスタムロールの利用は基本的には推奨されていません。（Permissionの頻繁な更新があるため、と理解しています）
最小権限を目指すと使いたくなるのですが、推奨されていない以上、極力、事前定義ロールを利用した方が良いかと思います。

### Service Account (Service Agent)
Google Workspaceからリンクされている各自のID(User)とは別に、サービスアカウントと呼ばれるリソース（AWSでいうサービスロールのようなもの）を作成できます。

https://cloud.google.com/iam/docs/service-account-overview

CloudRunやAppEngine等、GCP環境上で稼働するリソースに対して付与して使うことを想定されており、Permissionを適切に付けることで、アプリリソースが必要以上に強い権限を持つことを防ぐことができます。

なお、GCPマネージドのサービスアカウント（サービスエージェントとも呼ばれます）もあります。
サービスエージェントはAWSのサービスリンクロールに似ています。
基本的にはその関連サービスのAPIを有効化した時点（もしくはAPIを利用した時点）で自動的に生成されますので、初めから全て存在しているわけではありません。

サービス間のアクセス許可（例えば、CMEKの暗号化／複合化の権限をCloud Storageに付与する、等）をこのサービスエージェントを使って調整します。
サービスエージェントの一覧は下記にあります。

https://cloud.google.com/iam/docs/service-agents


### 認証
ローカル環境などのGCP外の環境から認証を通す際、下記2種類のコマンドがあります。

```
gcloud auth login
gcloud auth application-default login
```

前者は`gcloud`や`gsutil`等のCLI操作に使われ、後者は各言語のSDKを利用したアプリケーションをGCP外で動かす際の認証情報取得に使われます。

https://cloud.google.com/docs/authentication/gcloud

https://cloud.google.com/docs/authentication/client-libraries

後者はADC（Application Default Credential）と呼ばれていますが、実際にコマンドを実行すると下記にCredentialファイルが生成されます。
`~/.config/gcloud/application_default_credentials.json`
この2種類の認証を意識しておかないと、ADCのCredentialファイルのみ古い状態になっていてなぜかエラーになる、といったケースが発生する可能性があります。
ちなみに、`gcloud auth login --update-adc` とすれば両方一度に設定できて便利なのですが、コマンドを別々に投げる場合とで上記 Credential ファイルの中身が微妙に異なるケースがあります。（ややこしいのでこの話はまた別の機会に書こうと思います）

なお、AWSと同様にサービスアカウントキー（アクセスキー）の利用は極力避ける、というのは共通です。


## VPC Service Control
VPC Service Control はいわゆる境界防御のサービスで、各サービスAPIへのin/outを制限できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/852059/f3611587-4810-f02e-9a4f-cd9cb296c2f4.png)
参照：https://cloud.google.com/vpc-service-controls/docs/overview

AWSで例えると、よく「VPC Endpoint」だと言われますが、実態は似てるようで似ておらず、設定方法も ~~複雑怪奇~~ 印象が異なり、そもそもVPC内のサービスというわけではないので名前に釣られてはいけません。
境界はVPC単位ではなく、Project or Folder 単位となります。
また、全てのサービスが対応しているわけではないので、下記の対応サービスのドキュメントを確認してください。

https://cloud.google.com/vpc-service-controls/docs/supported-products


なお、ポリシーに定義できるのは、あくまで各サービスAPI単位（Cloud Storage, App Engine等の単位）なので、例えば、「Storage A は境界内に入れたいけども、Storage B は外に出したい」といったことは出来ません。（両方とも入れた上て、一方だけリソース指定で別の制御をすることは出来ます）
また、Google内部のアクセス（各サービスから内部的に発生するアクセス）についても全て定義する必要があるため、DryRunモードで運用しつつログで確認しながら調整が必要です。
机上の設計だけでは完全なものを作るのは難しいと思いますので、ある程度期間を見据えて設定していく必要があります。
（Private Google Access と組み合わせると追加の対応が必要だったり等、他にもハマりどころがたくさんありますが、長くなるのでドキュメントだけ置いておきます）

https://cloud.google.com/vpc-service-controls/docs/private-connectivity


## メール
Google Identity Platform や Monitor 等、機能の一部としてメールが配信される機能はありますが、AWS の SES のような純粋なメール配信サービスは GCP には現状存在しません。
そのため、アプリケーションからメールを配信する機能が必要な場合は外部サービス（SES や SendGrid 等）を利用するか、自前でメールサーバを立てるしかありません。
アプリを構築するタイミングになって「あれ？メールどうするの？」とならないように、あらかじめ検討が必要です。
何気に面倒なので、SES 類似サービスが出てくるのを心待ちにしてたりします。

---

以上、GCPでハマりがちなポイントをピックアップしてみました。
私の試行錯誤が、どなたかの役に立ちますように。

---

Japan Digital Design株式会社では、一緒に働いてくださる仲間を募集中です。カジュアル面談も実施しておりますので下記リンク先からお気軽にお問合せください。

https://japan-d2.com/careers

 

この記事に関するお問い合わせはこちら

https://japan-d2.com/contact

 

--- 
Technology & Development Div.
Infra Engineer

Yuki Watanabe