dbt docs ホスティング構成：S3 + CloudFront + GitHub Actions（OIDC認証）

## ゴール

今回の記事では、以下の構成を実現します：

* `dbt docs` を HTMLとして自動生成
* S3バケット（非公開）にアップロード
* CloudFront + OAC で高速・HTTPS配信
* GitHub Actions + OIDC による安全なCI/CD


## システム構成図

```
GitHub Actions
   │
   └── OIDC ▶ IAMロール（限定権限）
                   │
                   ├──▶ S3（private）
                   │       ▲
                   │       └── CloudFront（OAC）+ WAF（Web ACL）
                   │
                   └──▶ CloudFront キャッシュ無効化
```


## 1️⃣ S3バケットの作成（dbt docs 保存先）

### 設定：

| 項目            | 設定内容                 |
| ------------- | -------------------- |
| バケット名         | `dbt-docs-bucket`    |
| リージョン         | `ap-northeast-1`（東京） |
| パブリックアクセスブロック | ✅ すべて有効（非公開）         |
| 静的ウェブホスティング   | ❌ 不要（CloudFront経由）   |


## 2️⃣ CloudFront ディストリビューションの作成（OAC + S3バケット連携）

### 📌 **重要：バケット選択時のポリシー自動コピー**

CloudFront作成時にオリジンとしてS3バケットを選ぶと、以下の操作ができます：

#### ✅ オリジン設定時の手順：

1. cloudfrontから「**ディストリビューション**」を選択
2. オリジンドメインに `dbt-docs-bucket.s3.amazonaws.com` を選択
3. 「オリジンアクセス」→ `OAC（オリジンアクセスコントロール）` を選択（推奨）
4. ✅ **「バケットポリシーをコピーして貼り付ける」ボタンをクリック**
![スクリーンショット 2025-05-17 2.42.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3364428/8dc40e1e-d895-42cf-8e02-2d2a979d7324.png)

5. 表示されたJSONをコピー

#### ⬇️ S3側のバケットポリシーに貼り付け：

例（AWSが生成する形式）：

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowCloudFrontReadAccess",
      "Effect": "Allow",
      "Principal": {
        "Service": "cloudfront.amazonaws.com"
      },
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::dbt-docs-bucket/*",
      "Condition": {
        "StringEquals": {
          "AWS:SourceArn": "arn:aws:cloudfront::<YOUR_ACCOUNT_ID>:distribution/<YOUR_DIST_ID>"
        }
      }
    }
  ]
}
```



## 3️⃣ GitHub Actions 用 IAMロールの作成（OIDC）

IAM → ロール作成 → 「信頼ポリシー」：

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::<ACCOUNT_ID>:oidc-provider/token.actions.githubusercontent.com"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "token.actions.githubusercontent.com:sub": "repo:<ORG>/<REPO>:ref:refs/heads/main"
        }
      }
    }
  ]
}
```

IAMポリシー（最低限）：

```json
{
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:PutObject",
        "s3:DeleteObject",
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::dbt-docs-bucket",
        "arn:aws:s3:::dbt-docs-bucket/*"
      ]
    },
    {
      "Effect": "Allow",
      "Action": "cloudfront:CreateInvalidation",
      "Resource": "*"
    }
  ]
}
```


## 5️⃣ GitHub Actions ワークフロー（自動デプロイ）

```yaml
name: Deploy dbt Docs to S3 + CloudFront via OIDC

on:
  push:
    branches:
      - main

permissions:
  id-token: write
  contents: read

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: '3.9'

      - name: Install dbt
        run: |
          pip install dbt-core dbt-snowflake #←任意のDB
          dbt deps

      #- name: Generate dbt docs
      #  run: dbt docs generate --profiles-dir ./.dbt

      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v2
        with:
          role-to-assume: arn:aws:iam::<ACCOUNT_ID>:role/GitHubActionsDbtDocsDeployRole
          aws-region: ap-northeast-1

      - name: Upload docs to S3
        run: |
          aws s3 sync target/ s3://dbt-docs-bucket/ \
            --delete \
            --cache-control "max-age=3600" \
            --acl bucket-owner-full-control

      - name: Invalidate CloudFront cache
        run: |
          aws cloudfront create-invalidation \
            --distribution-id <YOUR_DIST_ID> \
            --paths "/*"
```



## ✅ 動作確認方法

```
https://<your-dist-id>.cloudfront.net/index.html
```

> `/` だけでは 403 または空ページになるため、
> CloudFront で `index.html` を明示します。

![スクリーンショット 2025-05-17 11.55.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3364428/e6291966-0f0c-4b9c-b06c-13976cce47fa.png)


## ✅ 拡張ポイント

| 機能               | 方法                                               |
| ---------------- | ------------------------------------------------ |
| カスタムドメイン         | Route53 + ACM + CloudFront                       |
| 認証制御             | WAFでIP制限 or Lambda\@EdgeでBasic認証                 |
| staging/prod環境分離 | S3バケット & CloudFront をブランチやGitHub Environmentsで切替 |
| ドキュメントのバージョン管理   | `target/`を`target/v1/`, `v2/`のように分割して同期          |



## まとめ

この構成を使えば、dbt docs をS3に非公開で保管しつつ、CloudFront経由で安全に配信できます。GitHub ActionsとOIDCによる自動デプロイで運用も手軽になり、WAFで最低限の保護も可能です。さらに、今後SSOやIP制限などの認証機構を組み合わせれば、より安心して社内公開できます。
まずはこの構成から始めて、必要に応じて拡張していくのがおすすめです。