[AWS] V0を使ったサイト、コマンド一撃で本番公開したいよな。[CI/CDパイプライン]

## 何ができるようになるのか

![anshin.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3908981/f1b8438e-c839-533e-42cf-8bff15919137.jpeg)

v0でモックアップ作れるのはすごいけど、本番上げるの簡単じゃない。

***だから簡単にしてみた！***

以下がコマンド一撃でできちゃうぜ。

| 項目 | 解説 |
|---|---|
| **Next.jsのビルド** | `npm run build` コマンドを実行して、Next.jsプロジェクトをビルドし、静的ファイルを生成。 |
| **デプロイ先の切り替え** |  ステージング環境と本番環境など、複数のデプロイ先を切り替える機能つき！ |
| **ロールバック** |  デプロイに失敗した場合に、以前のバージョンにロールバック！ |
| **S3へのデプロイ** | `aws s3 sync` コマンドを実行して、ビルドされた静的ファイルをS3バケットにアップロードします。 `--delete` オプションを指定することで、S3バケットに存在するがローカルにはないファイルを削除し、常に最新の状態を維持。 |
| **CloudFrontキャッシュの削除** | CloudFrontのキャッシュ削除をいちいちコンソールからやってられるかよ！自動化しといたぜ！？ |
| ***セキュリティスキャン*** | 静的セキュリティスキャンや依存関係の脆弱性スキャンを実行して、セキュリティリスクだって早期に検出！ | 


もちろんバージョン管理したいよな！安心してくれ！GitHub経由だ！


## どんなものを作るのか

![v0-.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3908981/e7764367-6721-bf6f-c58d-fff8d35d3936.jpeg)



## 前提
Mac, v0, AWS, github(GithubActions), Next.js 使ってる人向け。

## 1.v0からソースコードをローカルに落とす
わかってるだろうから読み飛ばしていいぜ！
1-1. v0の右上にadd to Codebaseってボタンがあるので、それをクリック
![スクリーンショット 2024-10-14 11.50.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3908981/c09b0af6-e81a-3296-45b6-c6c23d52705d.png)

1-2.すると、npx shadcn@latest add "URL" ってのがコピーできるセクションが出てくるのでコピー
![スクリーンショット 2024-10-14 11.53.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3908981/3e3e5463-24f9-ee84-b3b2-f7c48db1e63f.png)

1-3.ローカルのターミナルから任意のディレクトリ上で先のnpxコマンドを実行。

## 2.AWS - Route53
まずはドメインをとろう。

検索窓に「Route53」と入れよう。
![Route53-01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3908981/08ccc5b1-f0f9-83ab-c68d-a7a9e25782de.jpeg)

⭐︎を入れておくとよく利用するサービスをピン留めできる。
![Route53-02-.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3908981/1dfa09e9-4929-0b12-f5e9-0bb53fb27402.jpeg)

Route53をクリックする。
![Route53-04.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3908981/75df3233-64ac-97a6-67b3-d036bb946311.jpeg)

Route53のコンソールに入ったら「ドメインの登録」をクリック
![Route53-05.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3908981/5f04b805-f70d-29a2-15ce-2f04c37240db.jpeg)

「ドメイン名を入力」で検索をかける。
![Route53-06.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3908981/26a2dc40-9fe6-2cbc-f741-962d54acf28b.jpeg)

取得可能なドメイン名を見つけたら選択する。
![Route53-07.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3908981/7c85d0d1-81c2-cdd7-398d-6a905064c910.jpeg)

選択したら「チェックアウトに進む」をクリック
![Route53-08.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3908981/b29c5be9-0d84-a8c2-93f7-7f08b8f4d3f3.jpeg)

必要情報を入力する
![Route53-09.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3908981/85441b6d-bef8-2f22-785f-50a1cde159af.jpeg)

この時点で認証用メールが飛ぶので確認しておこう。
ステータスが「成功」になったらドメインの取得は完了だ！
![Route53-10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3908981/3f1cdfe4-037d-c396-6805-acba4d60c3f6.png)


## 3.AWS - ACM(AWS Certificate Manager)
続いて証明書の取得。
「AWS Certificate Manager」を使うよ。
![ACM-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3908981/c049698c-66dc-1889-4d16-234d1a25f445.png)

***このとき、絶対にリージョンをバージニア北部(us-east-1)にすること！***
そうしないとやり直しになるよ。
![ACM-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3908981/9363c4ba-5db4-e67f-0002-3f9a67101596.png)

リージョンが変更されたら、「リクエスト」をクリック。
![ACM-03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3908981/cfb9ed71-6519-853e-7d9d-7f8dba078207.png)

「パブリック証明書をリクエスト」にチェックを入れて「次へ」をクリック。
![ACM-04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3908981/dc277030-463e-a0da-3dde-d2d5b9e3d6ab.png)



SSL/TLS証明書のリクエスト: ACMを使用して無料のSSL/TLS証明書をリクエスト。
ドメインの検証: DNS検証（Route 53を使用している場合は自動化が容易）またはメール検証を行う。
DNS検証が便利で圧倒的おすすめ。

「この証明書に別の名前を追加」をクリックしてサブドメイン
*.<証明書取得対象のドメイン> も入力しておこう。

| 項目 | 解説 |
|---|---|
| **RSA 2048** | RSA 2048 は 2030 年までに安全ではなくなると予測されており、ECDSA への移行が推奨される。 |
| **ECDSA P 256** | 十分な強さでRSA2048より軽い。おすすめ |
| **ECDSA P 384** | 強いけど重い |

![ACM-05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3908981/bd6e1667-8e16-cce8-6efd-2b64f3464bae.png)

続いて、「Route53でレコードを作成」をクリック。これで認証が進む
![ACM-06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3908981/b81ae8aa-8217-c757-9a9c-702fc61ec2e5.png)


「レコードを作成」をクリック
![ACM-07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3908981/aff8945f-86d7-ae6a-cb56-3489189a1d18.png)

レコードが作成される。
![ACM-08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3908981/25f73f08-1d84-86d0-8aed-15e6daf0e035.png)

しばらく待つと、
証明書のステータスが「発行済み」
ドメインのステータスが「成功」となる
![ACM-09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3908981/81c3cce3-8cdb-9a5b-7514-c4ea77e0be74.png)






## 4.AWS - S3
Next.jsのビルド成果物を保存するためのS3バケットを作成。
***バケットポリシー***
　└ パブリックアクセスを削除し、CloudFrontのOAI（Origin Access Identity）からのみアクセスを許可





## 5.AWS - CloudFront
S3さっきのバケットを指定
<font color="red">*S3バケットをオリジンに設定する場合、S3の「静的ウェブサイトホスティング用エンドポイント」ではなく、「バケット名.s3.amazonaws.com」の形式の通常エンドポイントを使用すること！</font>

メッセージとして「Webサイトエンドポイントを使うことをおすすめします」と出てくるはず、S3バケットで「静的ウェブサイトホスティング」を有効にしている場合、<bucket-name>.s3-website-<region>.amazonaws.com の形式を使うとS3がindexドキュメントやエラーページを返してくれるためだ。

しかし、CloudFrontを介してHTTPS化する際は、基本的に「通常のS3エンドポイント」を選択する方が望ましい。なぜなら、s3-website-で始まるウェブホスティング用のエンドポイントはHTTPSに対応していない。CloudFront経由の完全なHTTPS接続を行うには通常エンドポイントを選択し、CloudFront側でHTTPS終端を行うのがセオリーなのだ。
![スクリーンショット 2024-12-18 10.41.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3908981/62eab94e-fc54-6999-6499-ac41dc3e2d22.png)

・Supported HTTP versions
HTTP3を設定してあげると動画関連が高速化するらしい。
![スクリーンショット 2024-12-18 11.09.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3908981/31d2c1cf-2c12-bd42-4d25-f242a997de5e.png)

・Default Root Object
こだわりがなければ'index.html'を指定しよう。

![スクリーンショット 2024-12-18 11.07.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3908981/1737316b-b752-31e3-9522-7987bc23281f.png)

CloudFrontからさっきのS3バケットにアクセスできるよう権限を設定。
ポリシーをコピーして「S3バケットアクセス許可」に移動。
![スクリーンショット 2024-12-18 10.43.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3908981/4299d029-e76a-253d-daab-5e5d9bade311.png)

・エラーページを設定
![スクリーンショット 2024-12-18 11.35.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3908981/08745ec2-d2ae-0afc-bad7-4b94c20becea.png)



## 6.S3に移動: 
S3バケットポリシーに、先ほどコピーしたOAIを許可する設定を追加だ！
```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowCloudFrontAccess",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity YOUR_OAI_ID"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::<ドメイン名>/*"
        }
    ]
}
```
そして、「パブリックアクセスをブロック」設定をオンにする。
![スクリーンショット 2024-12-18 11.03.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3908981/eae4b2e6-5cba-b8ae-ce10-de9317f78eb2.png)


## 7.Route53へ移動
<font color="red">Aレコード</font>をCloudFront distribution(********.cloudfront.net)にエイリアスする


### その他
キャッシュポリシーの設定やエラーページの設定、WAF、ACMとかはお好みで！
ACMの設定した人はHTTP3を選択するのもおすすめ！


## 8.AWS - IAM
ユーザーを作り、権限 ***AmazonS3FullAccess, CloudFrontFullAccess*** を付与する。
アクセスキーIDとシークレットアクセスキーは、一度表示されたら二度と表示されないので必ず保管してくれよな！

![スクリーンショット 2024-10-14 12.26.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3908981/57fc0988-b3d3-9945-8db3-35509fbbfec3.png)


## 9.GitHub Actionsのワークフローファイルを作成
プロジェクトルートディレクトリ下に以下の階層とファイルをつくってくれ！
.github/workflows/deploy.yml

以下のソースコードをベースに
さっきつくったキミの情報に合わせて書き換えてくれれば簡単だ！
この記事で一番価値がある部分さ！

 ***deploy.yml の中身***
 

```
name: Deploy to S3

on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
    - name: Checkout code
      uses: actions/checkout@v2

    - name: Install dependencies
      run: npm install

    - name: Build project
      run: npm run build

    - name: Configure AWS credentials
      uses: aws-actions/configure-aws-credentials@v1
      with:
        aws-access-key-id: ${{ 自分のアクセスキーのID }}
        aws-secret-access-key: ${{ 自分のシークレットアクセスキーのID }}
        aws-region: ap-northeast-1

    - name: Deploy to S3
      run: aws s3 sync ./out s3://studio-ao.tokyo --delete

    - name: Invalidate CloudFront Cache
      run: aws cloudfront create-invalidation --distribution-id 自分のCloudFrontのディストリビューションID  --paths "/*"

```



## 10.GitHub設定
https://github.com/

そもそもGitHubアカウントない人は作ってくれ。
GitHubリポジトリにmainブランチを作成してローカルのプロジェクトルートディレクトリに紐づける。
ここは理解してる人が多いと思うので読み飛ばしていい。

### ローカルリポジトリとGitHubリポジトリを紐づける手順

GitHub Actions を利用するには、ローカルリポジトリとGitHubのリモートリポジトリを紐づける必要がある。
以下の手順に従って設定しような。

### 10-1. ローカルリポジトリの初期化

プロジェクトルートディレクトリで以下のコマンドを実行し、ローカルリポジトリを初期化します。

```bash
git init
```

### 10-2. リモートリポジトリの追加

以下のコマンドを実行し、GitHubで作成したリポジトリを `origin` という名前でリモートリポジトリとして追加します。

```bash
git remote add origin <リモートリポジトリのURL>
```

`<リモートリポジトリのURL>` は、GitHubのリポジトリページで確認できます。

### 10-3. 変更をコミット

以下のコマンドを実行し、変更をステージングエリアに追加します。

```bash
git add .
```

その後、コミットメッセージを付けてコミットします。

```bash
git commit -m "初期コミット"
```

### 10-4. リモートリポジトリにプッシュ

以下のコマンドを実行し、ローカルの `main` ブランチをリモートリポジトリの `main` ブランチにプッシュします。

```bash
git push -u origin main
```

`-u` オプションを付けることで、ローカルの `main` ブランチとリモートの `main` ブランチをトラッキングするように設定します。

これで、ローカルリポジトリとGitHubのリモートリポジトリが紐づけ完了だぜ！

## 11.GitHubリポジトリにシークレットを登録

GitHubリポジトリのSettings > Secrets and variables > Actions に、
さっきのAWSアクセスキーIDとシークレットアクセスキーを登録するんだ。

👇ここだよ！
![スクリーンショット 2024-10-14 12.43.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3908981/db5378d6-f7db-2c20-6f58-e6e5e69a4d9e.png)



## 12.コマンド
あとは以下のコマンドを打つだけで、自動的にビルドandデプロイandキャッシュ削除してくれるのだ！
```
git add . && git commit -m "変更内容の文章" && git push origin main
```
黄色いクルクルが緑に変わったらデプロイ成功だぜ！？
くぅ！気持ちいい！

![スクリーンショット 2024-10-14 11.55.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3908981/15ea3c00-d7d2-f65e-f322-d0b06b539a03.png)

以下の方法でファイルをクリックするだけでここまでのコマンドを自動で実行できるようになるぜ。

https://qiita.com/GeneLab_999/items/4edc7bf5a2fa159feb5f

以下の方法でDockに固定できるぜ。

https://qiita.com/GeneLab_999/items/32e7a6190b0490408886

#### pushに失敗する時
以下の記事を確認してくれ

https://qiita.com/GeneLab_999/items/2c1aeefddaab243f9855


## 13.あとがき
![happy.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3908981/6ca93704-28c5-3242-0717-718a03b13fc0.png)
おめでとう！！！ここまで長かったけど、頑張った君は幸せになれるぜ！
自動化最高！！！


## 以下の方法ならGitHub経由せずに自動化できる

上記の方法で挫折した時にどうぞ

https://qiita.com/GeneLab_999/items/0fc120d863228d19f081