個人的な備忘録：GitHub Actionsを使用して、mainブランチに変更があった場合にS3への自動デプロイを試してみた

## はじめに
GitHub Actionsを活用して、メインリポジトリに変更があった際に、自動でS3バケットへ変更をプッシュする仕組みを構築しました。

:::note note
**今回は、通っているITスクールのハッカソン用プロジェクトの要件に合わせて、この機能を実装しました。**
:::

なお、本記事は個人的な備忘録としてまとめたものです。***その点をご理解いただければ幸いです。***

## 書こうと思ったきっかけ
ハッカソンでチーム開発を進める中で、デプロイ作業を自動化したいと感じたことがきっかけです。

![Screenshot 2025-01-25 at 1.44.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/c06d3316-95b7-4b5d-61e1-67827deee5e2.png)

以前、バックエンドではGo言語を用い、変更があった際にECRへ自動的にプッシュする仕組みを構築しました。

**詳細はこちらの記事をご覧ください：**

https://qiita.com/free-honda/items/da83c5dd44650c883164

https://qiita.com/free-honda/items/37edfb2ce5e14d4c8693

***今回は特に、S3バケットへの手動操作を減らし、効率的な開発環境を整備したいと考え、この機能を実装しました。***

## 実際にやってみた
以下の手順で、S3バケットの作成からGitHub Actionsを利用したデプロイのセットアップまでを説明します。

なお、GitHub ActionsでS3バケットにアクセスするためのIAMユーザーを作成し、アクセスキーIDとシークレットキーを取得済みであることを前提としています。

### 1. AWS CLIでS3バケットを作成

以下のコマンドを実行して、S3バケットを作成します。

```bash
aws s3api create-bucket \
  --bucket my-github-actions-bucket \
  --region ap-northeast-1 \
  --create-bucket-configuration LocationConstraint=ap-northeast-1
```

**コマンドの説明**

- `aws s3api create-bucket` : S3バケットを作成するコマンド。
- `--bucket my-github-actions-bucket` : バケット名（ユニークな名前を指定）。
- `--region ap-northeast-1` : リージョンを東京リージョンに設定。
- `--create-bucket-configuration LocationConstraint=ap-northeast-1` : 東京リージョンをバケットに適用（必要に応じて設定）。

### 2. バケット作成の確認
バケットが正しく作成されたかどうかを確認するには、以下のコマンドを実行します

```bash
aws s3 ls
```

出力結果に `my-github-actions-bucket` が表示されていれば、バケットの作成に成功しています。

### 3. パブリックアクセスの変更（任意）
デフォルトでは、S3バケットは「パブリックアクセスをブロックする」設定が有効になっています。**この設定を無効化する必要がある場合、以下の手順で変更します。**

- **対象のバケットを選択**
  - 対象のバケット（例：`my-github-actions-bucket`）を選択します。

- **「パブリックアクセスのブロック（バケット設定）」を編集**
  - バケットの設定画面で「パブリックアクセスのブロック」を編集し、必要に応じてアクセス権限を調整します。


![Screenshot 2025-01-27 at 8.46.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/94d45e2f-5e5b-e23d-36fb-de184aa43734.png)

なお、パブリックポリシーが不要な場合は、この設定を無効化せず、非公開のまま運用することを検討してください。

:::note alert
**※注意点**

- **セキュリティリスク**
  - パブリックポリシーを適用すると、バケットがインターネット上からアクセス可能になる場合があります。
  - 必要最小限のアクセス権を付与することをお勧めします。
  - 特定のユーザーやサービスだけにアクセスを許可する場合は、`"Principal": "*"` を適切に制限してください（例：IAMユーザーやロールを指定）。
:::

### 4. GitHub SecretsにAWS認証情報を設定

- **GitHubリポジトリにアクセス**
  - 対象のリポジトリに移動します。

- **Secretsの設定**
  1. 「Settings」→「Secrets and variables」→「Actions」を開きます。
  2. 「New repository secret」をクリック。
  3. 以下の情報を追加します：
     - **`AWS_ACCESS_KEY_ID`**: IAMユーザー作成時に取得したアクセスキーID。
     - **`AWS_SECRET_ACCESS_KEY`**: IAMユーザー作成時に取得したシークレットキー。

### 5. `.github/workflows/deploy_to_s3.yml` の作成

以下の内容で `deploy_to_s3.yml` ファイルを作成します。`your-bucket-name` を、作成したS3バケットの名前に置き換えてください。

```.github/workflows/deploy_to_s3.yml
name: Deploy to S3

on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
    # Checkout the repository
    - name: Checkout code
      uses: actions/checkout@v3

    # Configure AWS credentials
    - name: Configure AWS credentials
      uses: aws-actions/configure-aws-credentials@v2
      with:
        aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
        aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
        aws-region: ap-northeast-1 # Tokyo region

    # Sync files to S3
    - name: Sync files to S3
      run: |
        aws s3 sync . s3://my-github-actions-bucket \
          --exclude ".git/*" \
          --exclude ".github/*" \
          --delete
```

## 実際に実行してみた
ここでは、実際にメインブランチに `test.html` を新たに作成し、デプロイを試してみました。

![Screenshot 2025-01-27 at 9.06.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/f27c0d06-5496-2b73-ea6e-fb5b2231285d.png)

「Actions」タブを開き、ジョブが正常に実行され、成功していることを確認できました。

![Screenshot 2025-01-27 at 8.54.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/10292d12-4d4d-5865-27c5-343f9c80a37c.png)

また、AWS管理コンソールでS3バケットを確認したところ、ファイルが正常にアップロードされていることを確認しました。これにより、検証は成功です。

![Screenshot 2025-01-27 at 8.55.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/28e06a14-32ad-90b3-401f-ceb87c152b23.png)

## まとめ
今回、GitHub Actionsを使った自動デプロイの設定を実装し、S3バケットへの変更同期を無事に成功させました。

:::note warn
**手動作業を減らし、効率的な運用を目指す第一歩として、大きな学びを得ることができたと感じています。**
:::

***この記事が、同じ課題に直面している方々の技術的な参考になれば幸いです。***