0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

AWS AppRunnerにデプロイする前に、GithubActionsを経由してテストを行う

Last updated at Posted at 2022-12-13

AWS App Runner Advent Calendar 2022の14日目の記事です。

AWS AppRunnerはさまざまな言語に対応し始めていたり、GithHubのブランチを監視して自動デプロイしてくれたり、オートスケールもある程度できたり、インフラの高度な知識がなくてもデプロイができる大変便利なサービスです。

任意のブランチを監視して、コミットされたら自動デプロイされる機能はとても便利なのですが、間にテストなどを挟めないので、バグが残ったままのコードがデプロイされ得る状態です。

今回は、Github Actionsを経由してAppRunnerにデプロイしてみようと思います。

[問題点]
awslabs/amazon-app-runner-deployを使っていますが、AutoDeploymentsEnabledが指定できないため、デフォルトのtrueとなっています。
このままではGithub Actions側でデプロイする際に既にデプロイが開始しているのでコンフリクトしてしまいます。なので、この方法はまだ実運用は非推奨です。

この記事公開後にプルリクエスト をする予定です。近々対応されたら追記します。

前提

  • 開発環境と本番環境、そしてレビュー用の環境があるという過程で行います。
  • 東京リージョンを使います
  • 実行環境はNode.jsです
  • 今回はコンテナリポジトリからのデプロイではなくソースコードデプロイを想定します

事前準備

1. GitHubと連携する

この工程は、リポジトリ/Organizationのオーナーが行う必要があります。

2. 開発環境と本番環境のServiceを作る

固定のServiceとして、開発環境と本番環境用のServiceを事前に作っておきます。
サクッとaws cliから作っちゃいます。
このときに作ったarnを控えておきます。

{{}}内はご自身の環境に読み替えてください

例えばyarnを使う僕の場合、BuildCommandyarn install && yarn buildStartCommandyarn start:prodとしています

開発環境
aws apprunner create-service --service-name {{service-name}}_develop --source-configuration \
              '{
                "AuthenticationConfiguration": {
                    "ConnectionArn": "{{Github Connection arn}}"
                },
                "AutoDeploymentsEnabled": false,
                "CodeRepository": {
                    "RepositoryUrl": "{{RepositoryUrl}}",
                    "SourceCodeVersion": {
                        "Type": "BRANCH",
                        "Value": "develop"
                    },
                    "CodeConfiguration": {
                        "ConfigurationSource": "API",
                        "CodeConfigurationValues": {
                            "Runtime": "NODEJS_16",
                            "BuildCommand": "{{依存関係の解決・ビルドコマンド}}",
                            "StartCommand": "{{アプリケーションを立ち上げるコマンド}}",
                            "Port": "3000",
                            "RuntimeEnvironmentVariables":
                                {
                                    "NODE_ENV": "production"
                                }
                        }
                    }
                }
              }'

本番環境
aws apprunner create-service --service-name {{service-name}}_production --source-configuration \
              '{
                "AuthenticationConfiguration": {
                    "ConnectionArn": "{{Github Connection arn}}"
                },
                "AutoDeploymentsEnabled": false,
                "CodeRepository": {
                    "RepositoryUrl": "{{RepositoryUrl}}",
                    "SourceCodeVersion": {
                        "Type": "BRANCH",
                        "Value": "main"
                    },
                    "CodeConfiguration": {
                        "ConfigurationSource": "API",
                        "CodeConfigurationValues": {
                            "Runtime": "NODEJS_16",
                            "BuildCommand": "{{依存関係の解決・ビルドコマンド}}",
                            "StartCommand": "{{アプリケーションを立ち上げるコマンド}}",
                            "Port": "3000",
                            "RuntimeEnvironmentVariables":
                                {
                                    "NODE_ENV": "main"
                                }
                        }
                    }
                }
              }'

3. Github Secretを設定する

workflowから読み取る環境情報や、シークレットなどをリポジトリSecretsに設定していきます。

本当は、Environments Secretsを使った方がいいのですが、読みやすさの便宜上割愛します

AWS_APPRUNNER_ACCESS_KEY_IDAWS_APPRUNNER_ACCESS_SECRET_KEYはそれぞれ、AWSAppRunnerFullAccessポリシーを付与したIAMユーザーのアクセスキーとシークレットキーです。

image.png

より良い命名があったら教えてください。

Developにマージされたら開発環境のServiceにデプロイする

基本的なことしかしてません。developブランチにコミットされたらテストを実行し、テストがパスしたら先ほど作成した開発環境のServiceにデプロイします。

develop.yml
name: Test & Deploy to develop

on:
  push:
    branches:
      - "develop"

jobs:
  test:
    permissions:
      id-token: write
      contents: read
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3

    - name: Setup Node.js environment
      uses: actions/setup-node@v3.5.1
      with:
        node-version: 16.18.0
    - name: Run test
      run: |
        npm install
        npm run test
  deploy:
    needs: test
    environment: develop
    runs-on: ubuntu-latest
    steps:
        - uses: actions/checkout@v3

        - name: Configure AWS Credentials
          uses: aws-actions/configure-aws-credentials@v1
          with:
            aws-region: "ap-northeast-1"
            aws-access-key-id: ${{ secrets.AWS_APPRUNNER_ACCESS_KEY_ID }}
            aws-secret-access-key: ${{ secrets.AWS_APPRUNNER_ACCESS_SECRET_KEY }}

        - name: deploy to app runner
          run: |
            aws apprunner start-deployment --service-arn ${{ secrets.DEVELOP_APPRUNNER_SERVICE_ARN }}

参考

PullRequestがOpenしたらレビュー用のサービスを作成する&コミットされたら更新する

PullRequestを発行したらレビュー用のサービスを作成します。
デプロイが完了したら、ホスティング先のURLをコメントで残します。
スクリーンショット 2022-12-13 15.54.04.png

wait-for-service-stability-secondsでデプロイが完了するのを待機できます。
デプロイにかかる時間はアプリケーションの規模やコード量によって変わりますのでご自身で調整してみてください。

review-create.yml
name: Test & Create Review Service

on:
  pull_request:
    types: [ labeled, ready_for_review ]

jobs:
  test:
    permissions:
      id-token: write
      contents: read
    if: ${{ github.base_ref != 'main' }}
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3

    - name: Setup Node.js environment
      uses: actions/setup-node@v3.5.1
      with:
        node-version: 16.18.0

    - name: Test
      run: |
        npm install
        npm run test

  deploy:
    runs-on: ubuntu-latest
    needs: test
    env:
      PR_NUMBER: ${{ github.event.number }}
    outputs:
      service-url: ${{ steps.deploy-apprunner.outputs.service-url }}
    steps:
      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v1-node16
        with:
          aws-region: "ap-northeast-1"
          aws-access-key-id: ${{ secrets.AWS_APPRUNNER_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_APPRUNNER_ACCESS_SECRET_KEY }}

      - name: Deploy to App Runner
        id: deploy-apprunner
        uses: awslabs/amazon-app-runner-deploy@main
        env:
          SERVER_PORT: 3000
          NODE_ENV: develop
        with:
          service: review-app_${{ github.event.repository.name }}_${{ env.PR_NUMBER }}
          source-connection-arn: ${{ secrets.APPRUNNER_GITHUB_CONNECTION_ARN }}
          repo: https://github.com/${{ github.repository }}
          branch: ${{ github.head_ref }}
          runtime: NODEJS_16
          build-command: yarn install && yarn build
          start-command: yarn start:prod
          port: ${{ env.SERVER_PORT }}
          region: ap-northeast-1
          cpu : 1
          memory : 2
          wait-for-service-stability-seconds: 600
          copy-env-vars: |
            NODE_ENV

  comment:
    runs-on: ubuntu-latest
    permissions: write-all
    needs: deploy
    env:
      PR_NUMBER: ${{ github.event.number }}
    steps:
      - uses: actions/checkout@v3

      - name: Comment Review App URL
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          gh pr comment ${{ env.PR_NUMBER }} --body "App runner URL https://${{ needs.deploy.outputs.service-url }}"

PullRequestがMerge、Closeされたらレビュー用のサービスを削除する

コードレビューが完了し、役目を終えたサービスを削除することでクリーンアップします(そうしないと課金が止まりませんからね)

Runnning状態のものしか停止できません。

review-delete.yml
name: Delete Review Service

on:
  pull_request:
    types: [ closed ]

jobs:
  delete:
    runs-on: ubuntu-latest
    steps:
        - uses: actions/checkout@v3
        - name: Configure AWS Credentials
          uses: aws-actions/configure-aws-credentials@v1
          with:
            aws-region: "ap-northeast-1"
            aws-access-key-id: ${{ secrets.AWS_APPRUNNER_ACCESS_KEY_ID }}
            aws-secret-access-key: ${{ secrets.AWS_APPRUNNER_ACCESS_SECRET_KEY }}

        - name: Get Service Arn
          id: get-service-arn
          env:
            PR_NUMBER: ${{ github.event.number }}
          run: |
            SERVICE_ARN=`aws apprunner list-services --query "ServiceSummaryList[?ServiceName=='review-app_${{ github.event.repository.name }}_$PR_NUMBER']|[0].ServiceArn"`
            echo "service-arn=$SERVICE_ARN" >> $GITHUB_OUTPUT

        - name: Delete AppRunner Service
          run: |
            aws apprunner delete-service --service-arn ${{ steps.get-service-arn.outputs.service-arn }}

改善箇所

僕がどうにかできることではないですが、デプロイ中は何も操作ができないのは解消されると幅が広がりますね。

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?