GitHub Actions 踏み台サーバからECSへデプロイ

# 背景

GitHub ActionsのDeploy to Amazon ECSを使ってデプロイしようとしたのだが、管理ポリシーでユーザーにIP制限をかけていたので、ECRへのログインが失敗した。調べていると以下の記事を見つけた。

https://qiita.com/gdtypk/items/aea503db22dfc79f4e9e

この参考記事ではタイトルにある通りEC2へデプロイしている。本記事ではEC2を踏み台サーバにし、ECSへデプロイできるか動作検証したものである。

# 1. 踏み台サーバをたてる
ECRへのログインとECS Fargateのタスク実行権限を許可するロールをアタッチしたEC2を起動する。gitとdockerをインストールしておく。

# 2. GitHubへのSSH接続用の公開鍵・秘密鍵を生成

こちらの記事を参考にした。

https://qiita.com/shizuma/items/2b2f873a0034839e47ce

メモ用に以下に記しておく。

```
$ cd ~/.ssh
$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/ec2-user/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/ec2-user/.ssh/id_rsa.
Your public key has been saved in /home/ec2-user/.ssh/id_rsa.pub.
$ ls
authorized_keys  id_rsa  id_rsa.pub
```

# 3. 公開鍵をGitHubに登録

`id_rsa.pub`を以下のように登録する。

**3-1. settingsを選択**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/418eca61-3441-75e0-f473-73f5718b3be5.png)

**3-2. SSH and GPG keysを選択**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/7d88ee63-6607-8628-af9c-8c719dd48a32.png)

**3-3. New SSH keysを選択**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/038be605-1e0d-b08b-326d-ae59444f771f.png)

**3-4. 公開鍵を貼り付ける**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/064982bb-e41e-9e4b-8b97-0c32ef4ab0da.png)

# 4. Gitリポジトリを作成する

リポジトリはこちらの記事で作成したものを使う。

https://qiita.com/quryu/items/9d9fd931ab8ade667150

# 5. GitHub Actionsのyamlファイルを作成する

冒頭にも書いた通り、こちらの記事で紹介されているyamlファイルをECS用に少し書き換えるだけである。

https://qiita.com/gdtypk/items/aea503db22dfc79f4e9e

yamlファイルで使用している変数をまとめた。

|||
|---|---|
|AWS_ACCESS_KEY_ID|AWSのアクセスキーID（Secretsに登録）|
|AWS_SECRET_ACCESS_KEY|AWSのシークレットキー（Secretsに登録）|
|PRIVATE_KEY|EC2ログイン用のSSHキー（Secretsに登録）|
|DNS_NAME|EC2のDNS名*1（Secretsに登録）|
|account_id|AWSのアカウントID|
|git_repository_name|GitHubのリポジトリ名|
|git_user_name|GitHubのユーザー名|
|ecr_repository_name|ECRのリポジトリ名|
|cluster_name|ECSのクラスター名|
|task_difinition_name|ECSのタスク定義の名前|
|subnet_id|サブネットID|
|security_group_id|セキュリティグループID|

*1：DNS名と書いてしまったが、ユーザー名も含んでいる。例えば、`ec2-user@ec2-52-123-123-12.ap-northeast-1.compute.amazonaws.com`という値をSecretsに格納する。

```yaml
name: TestDeploy

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:

      - uses: actions/checkout@v2
      - name: test-clone
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          PRIVATE_KEY: ${{ secrets.PRIVATE_KEY }}
          DNS_NAME: ${{ secrets.DNS_NAME }}
        run: |
          curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
          unzip awscliv2.zip
          sudo ./aws/install --update -i /usr/local/aws-cli -b /usr/local/bin
          
          printf "$AWS_ACCESS_KEY_ID\n$AWS_SECRET_ACCESS_KEY\nap-northeast-1\njson\n" | aws configure
          aws configure list
          echo "$PRIVATE_KEY" > private_key && chmod 600 private_key
          sudo ssh -o StrictHostKeyChecking=no -i private_key $DNS_NAME '

          ssh -o StrictHostKeyChecking=no -T git@github.com
          if [ -d git_repository_name ]; then
            rm -rf git_repository_name
          fi
          git clone git@github.com:git_user_name/git_repository_name.git
          cd git_repository_name

          aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin account_id.dkr.ecr.ap-northeast-1.amazonaws.com
          docker build -t ecr_repository_name .
          docker tag ecr_repository_name:latest account_id.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_repository_name:latest
          docker push account_id.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_repository_name:latest
          
          aws ecs run-task --cluster cluster_name \
          --launch-type FARGATE \
          --platform-version 1.4.0 \
          --task-definition task_difinition_name \
          --network-configuration "awsvpcConfiguration={subnets=[subnet_id],securityGroups=[security_group_id],assignPublicIp=ENABLED}"
          '
```

# 参考記事

https://qiita.com/gdtypk/items/aea503db22dfc79f4e9e

https://qiita.com/shizuma/items/2b2f873a0034839e47ce

https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/ECS_AWSCLI_Fargate.html