これは App Runner アドベントカレンダー の21日目です。
完全に年を跨いで最早あれなんですが、なんとか。。
あまり App Runner 本体のトピックではないが、CodeCatalyst で App Runner をにデプロイする記事を書こうと思う。
CodeCalyst で App Runner にデプロイする方法案
現状、App Runner のソールコードリポジトリプロバイダーは GitHub のみなので、CodeCatalys リポジトリ上からは直接デプロイできない。
GA時には、ここは App Runner のソースとしてサポートされることを期待。
よって自動デプロイを実現するには以下の2パターンが想定される
- ECRを使う
- ECR までは CodeCatalyst 側のワークフローで Push
- その後 Workflow 内で App Runner のサービスを更新する
- GitHub リポジトリとリンクさせる
今回は前者のECRを使う方法でやってみる。
CodeCatalyst準備
Project 作成
Repository 作成
- link repository で GitHub とリンクさせることも可能
Dev Environment 作成
GitHub Codespaces のような機能。裏側で開発用サーバーとその上にコンテナが立ち上がり、そこに IDE から接続することにより、どこからでも同一環境で開発できる。
IAM 接続方法
Dev Environment から IAM 利用する方法。
IAM の接続は Toolkit 経由で行うとあるがこれでできるのは VSCode Toolkit の機能のみであり、Terminal で使う場合は普通に Crendential から利用する必要がある模様。
IAM Role 連携できるようになることを期待する。
App Runner 用のソースコードの準備
Dev Environment として VSCode が使えるので、そこから App Runner のサンプルコードを CodeCatalyst のリポジトリに Push する。
https://github.com/aws-containers/hello-app-runner このリポジトリからCloneした内容を取り込み
$ cd .. $ mkdir origin-repo $ cd origin-repo/ $ git clone https://github.com/aws-containers/hello-app-runner.git Cloning into 'hello-app-runner'... remote: Enumerating objects: 115, done. remote: Counting objects: 100% (33/33), done. remote: Compressing objects: 100% (13/13), done. remote: Total 115 (delta 25), reused 20 (delta 20), pack-reused 82 Receiving objects: 100% (115/115), 446.01 KiB | 13.51 MiB/s, done. Resolving deltas: 100% (46/46), done. $ cp -r hello-app-runner/* ../hello-app-runner/
git push
$ git add . $ git commit -m "initial commit" [main f45a2b4] initial commit 34 files changed, 5120 insertions(+), 19 deletions(-) create mode 100644 ATTRIBUTION.md create mode 100644 Dockerfile create mode 100644 LICENSE create mode 100644 Notice.txt create mode 100644 Pipfile create mode 100644 Pipfile.lock create mode 100755 app.py create mode 100644 apprunner.yaml create mode 100644 banner_base_dark.png create mode 100644 banner_base_light.png create mode 100644 cf.yaml create mode 100644 requirements.txt create mode 100644 static/apprunner_icon.svg create mode 100644 static/background-mobile.svg create mode 100644 static/background.bak.svg create mode 100644 static/background.svg create mode 100644 static/banner.svg create mode 100644 static/banner_sample.png create mode 100644 static/banner_satellite.svg create mode 100644 static/banner_stars.svg create mode 100644 static/docs_icon.svg create mode 100644 static/external_link_icon.svg create mode 100644 static/favicon.svg create mode 100644 static/fonts/open-sans-v18-latin-regular.eot create mode 100644 static/fonts/open-sans-v18-latin-regular.svg create mode 100644 static/fonts/open-sans-v18-latin-regular.ttf create mode 100644 static/fonts/open-sans-v18-latin-regular.woff create mode 100644 static/fonts/open-sans-v18-latin-regular.woff2 create mode 100644 static/git_icon.svg create mode 100644 static/twitter_icon.svg create mode 100644 static/workshop_icon.svg create mode 100644 templates/index.html create mode 100644 templates/index.txt $ git push origin main Enumerating objects: 41, done. Counting objects: 100% (41/41), done. Delta compression using up to 2 threads Compressing objects: 100% (39/39), done. Writing objects: 100% (39/39), 434.75 KiB | 13.17 MiB/s, done. Total 39 (delta 5), reused 0 (delta 0), pack-reused 0 remote: Validating objects: 100% To https://git.us-west-2.codecatalyst.aws/v1/yasuhiro-horiuchi/hello-app-runner/hello-app-runner fa02be1..f45a2b4 main -> main
AWS リソースの準備
AWS リソースとして ECR と App Runner を用意する。
ECR の作成 by awscli
先に ECR 作っとかないと CDK コケるので。
CodeCatalyst の Dev Environment から実行する。
$ aws ecr create-repository --repository-name app-runner-hello $ aws ecr get-login-password --region us-west-2 | docker login --username AWS --password-stdin XXXXXXX.dkr.ecr.us-west-2.amazonaws.com $ docker build -t app-runner-hello . $ docker tag app-runner-hello:latest XXXXXXX.dkr.ecr.us-west-2.amazonaws.com/app-runner-hello:latest $ docker push XXXXXXX.dkr.ecr.us-west-2.amazonaws.com/app-runner-hello:latest
App Runner の作成 by CDK
なんとなく、App Runner は CDK で作成する。
App Runnerの作成はExperimentalなL2 Constructを使用する
https://constructs.dev/packages/@aws-cdk/aws-apprunner-alpha/v/2.59.0-alpha.0?
import * as cdk from 'aws-cdk-lib'; import { Construct } from 'constructs'; import * as apprunner from '@aws-cdk/aws-apprunner-alpha'; import * as ecr from 'aws-cdk-lib/aws-ecr'; export class AppRunnerHelloStack extends cdk.Stack { constructor(scope: Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); const service = new apprunner.Service(this, 'Service', { source: apprunner.Source.fromEcr({ imageConfiguration: { port: 80 }, repository: ecr.Repository.fromRepositoryName(this, 'App-Runner-Hello', 'app-runner-hello'), tagOrDigest: 'latest', }), serviceName: 'App-Runner-Hello', }); } }
$ npm install $ cdk deploy
デプロイ連携
CodeCatalyst Workflows により ECR に push して App Runner にデプロイさせる。
GitHub Actions が Workflows では使えるので、この App Runner の GitHub Actions を CodeCatlyst Workflows に持ち込んでみる。
https://github.com/awslabs/amazon-app-runner-deploy/blob/main/README.md#image-based-service
修正点
Secretsパラメータの修正
Secrets の記法が GitHub Actions と CodeCatalys で異なる。
${{ secrets.AWS_REGION }}
→ ${Secrets.AWS_REGION}
CodeCatalyst の場合不要なステップ削除
actions/checkout@
actions/checkout@
ステップは、CodeCatalyst の場合 Inputs.Sources
を指定するだけで良い
Inputs: Sources: - WorkflowSource
aws-credentials
aws-credentials
ステップは、CodeCatalyst だと CI/CD の Environments としてデプロイ先の AWSアカウントを定義することで代替する。
Environment では AWSアカウントと、そこで利用する IAM Role を指定する。
environmentの作成
IAM の設定で、CodeCatalystPreviewDevelopmentAdministrator ロールに AWSAppRunnerFullAccess ポリシーを追加。
Workflow の Configuration で Environment, Account, IAM Role を紐づける。
以下が Workflow.yaml に追記される
Environment: Connections: - Role: CodeCatalystPreviewDevelopmentAdministrator-d6mk1k Name: "XXXXXXXXXXXX" Name: dev
${{ github.sha }}
イメージタグとして ${{ github.sha }}
=コミットハッシュを利用している。
CodeCatalyst だと ${WorkflowSource.CommitId}
で取得できるので、これを利用する。
GitHub Actions のOutputパラメータ関連
CodeCatalyst では CodeCatalyst の Action 間のパラメータ受け渡しはできるが、同一 Actrion 内での Step 間の受け渡しができない。
以下の Output パラメータ利用しており、これを修正する。
${{ steps.login-ecr.outputs.registry }}
${{ steps.build-image.outputs.image }}
https://docs.aws.amazon.com/codecatalyst/latest/userguide/integrations-github-action-working.html
regstry について
Secrets で Registry 名は渡すことにした。
image について
image 名は、$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
で、 $IMAGE_TAG
は ${WorkflowSource.CommitId}
なので、別に受け渡さなくて作れる。
${Secrets.ECR_REGISTRY}/${Secrets.ECR_REPO}:${WorkflowSource.CommitId}
ちなみに1
別 Action の Output パラメータは${action-name.step-id_output-name}
で参照できるが同一Actionだと、Circular Dependencyエラーが出る
The workflow cannot be constructed because a circular dependency was detected for the actions or action groups [GitHubActions_1]. Verify the "DependsOn" and "Inputs" properties to ensure they are properly configured.
Action 分けると環境もわかれるのか、 login-ecr
と build-image
が別になると認証が引き継がれない。
ちなみに2
image 変数の引き継ぎは Action 分けてもなんとかなりそうなので、やってみたが、パラメータにシークレットが含まれると見做されて連携されない。
2023-01-14T03:27:12.4755637Z ##[warning]Skip output 'registry' since it may contain secret. 2023-01-14T03:27:12.4762083Z ##[warning]Skip output 'IMAGE' since it may contain secret.
image名にはリージョンが含まれるが、リージョンを Secret として定義しているためだった。
※シークレットを含めるとパラメータ連携しないのは、GitHub Actions の仕様。
Job outputs containing expressions are evaluated on the runner at the end of each job. Outputs containing secrets are redacted on the runner and not sent to GitHub Actions.
Secrets の追加
ということで、以下が必要な Secret となった。
Secrets.ECR_REPO
Secrets.ECR_REGISTRY
Secrets.ROLE_ARN
- CDKで自動生成される App Runner のロールを指定
Secrets.AWS_REGION
Secrets.APP_RUNNER_SERIVCE
Workflow これで動いた
.codecatalyst/workflows/Workflow.yaml
Name: Workflow_5012 SchemaVersion: "1.0" # Optional - Set automatic triggers. Triggers: - Type: Push Branches: - main # Required - Define action configurations. Actions: GitHubActions_1: Identifier: aws/github-actions-runner@v1 Inputs: Sources: - WorkflowSource Configuration: Steps: - name: Login to Amazon ECR id: login-ecr uses: aws-actions/amazon-ecr-login@v1 - name: Build, tag, and push image to Amazon ECR id: build-image env: ECR_REGISTRY: ${Secrets.ECR_REGISTRY} ECR_REPOSITORY: ${Secrets.ECR_REPO} IMAGE_TAG: ${WorkflowSource.CommitId} run: >- docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG . docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG - name: Deploy to App Runner Image id: deploy-apprunner uses: awslabs/amazon-app-runner-deploy@main with: service: ${Secrets.APP_RUNNER_SERIVCE} image: '${Secrets.ECR_REGISTRY}/${Secrets.ECR_REPO}:${WorkflowSource.CommitId}' access-role-arn: ${Secrets.ROLE_ARN} region: ${Secrets.AWS_REGION} cpu: 1 memory: 2 # wait-for-service-stability-seconds: 1200 Compute: Type: EC2 Environment: Connections: - Role: CodeCatalystPreviewDevelopmentAdministrator-d6mk1k Name: "XXXXXXXX" Name: dev
デプロイの確認
少しコードを修正して、CodeCatalyst リポジトリにプッシュすると、無事に App Runner に反映された。
完全に CodeCatalyst の検証記事みたいになってしまったが、デプロイ先が App Runner ということで許してください。
App Runner 用の Action の追加や、App Runner のソースリポジトリとしてのサポート等、AWSのサービスならではのネイティブ連携をGA時には期待する。
ちなみに
Dev Env は Amazon Linux2 が動く
$ cat /etc/os-release NAME="Amazon Linux" VERSION="2" ID="amzn" ID_LIKE="centos rhel fedora" VERSION_ID="2" PRETTY_NAME="Amazon Linux 2" ANSI_COLOR="0;33" CPE_NAME="cpe:2.3:o:amazon:amazon_linux:2" HOME_URL="https://amazonlinux.com/"
- awscli, cdk, docker, python(v3.9.14), pip (v3.9)使えた
デフォルトのdevfile.yml(/projects/devfile.yaml
)
schemaVersion: 2.0.0 metadata: name: aws-universal version: 1.0.1 displayName: AWS Universal description: Stack with AWS Universal Tooling tags: ["aws", "al2"] projectType: "aws" components: - name: aws-runtime container: image: public.ecr.aws/aws-mde/universal-image:latest mountSources: true volumeMounts: - name: docker-store path: /var/lib/docker - name: docker-store volume: size: 16Gi
VSCode Toolkit との連携いい感じ
存在しない Secret を読むとログなしでワークフロー失敗する
デプロイのタイミングが被ると App Runner で OPERATION_IN_PROGRESS でワークフロー失敗する
2023-01-14T08:41:29.0014539Z ##[error]Service cannot be updated in the current state: OPERATION_IN_PROGRESS.