LoginSignup
0
0

C#で作成したAWS Lambdaの関数をGitHub Actionsで自動デプロイする

Last updated at Posted at 2023-06-22

この記事について

AWS Lambda関数を作成した際、VSCodeを使用している場合は拡張機能を使用してローカルからAWSへデプロイすることが可能です。
しかし、Lambda関数の変更回数が多くなったり、チーム開発を行う場合にはローカルからの手動デプロイは手間になったり俗人化を招くこととなります。
そこでこの記事では、GitHub Actionsを使用してGitHubの特定のブランチにpushされたLambda関数をAWSへ自動デプロイする仕組みについて説明したいと思います。

対象読者

  • GitHubを使用してAWS Lambdaの開発を行っている方
  • チーム開発などでAWS Lambdaの自動デプロイを行いたい方

環境

内容 バージョン
.NET 6.0.x

.NET用のAmazon.Lambda.Toolsで下のコマンドで.NETプロジェクトを作成すると、以下のようなディレクトリ構成となります。
(プロジェクトファイルがSampleFunction/src/SampleFunction/SampleFunction.csprojに存在する)

% dotnet new lambda.EmptyFunction --name SampleFunction
テンプレート "Lambda Empty Function" が正常に作成されました。
% cd SampleFunction
% tree SampleFunction
SampleFunction
 ├── src
 │   └── SampleFunction
 │       ├── Function.cs
 │       ├── Readme.md
 │       ├── SampleFunction.csproj
 │       └── aws-lambda-tools-defaults.json
 └── test
     └── SampleFunction.Tests
         ├── FunctionTest.cs
         └── SampleFunction.Tests.csproj

今回はこちらの構成を想定してワークフローを作成していきます。
参考:【VSCode, C#, AWS Lambda】C#で作成したLambda Functionをローカルで動作確認する - プロジェクトの作成

TL;DR

masterブランチにpushされた時のみGitHub Actionsのジョブを実行するようにしています。

.github/workflows/lambda_deploy.yml
name: Deploy to AWS Lambda
on:
  push:
    branches:
      - master

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - 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: ${{ secrets.AWS_REGION }}

      - name: Setup dotnet
        uses: actions/setup-dotnet@v3
        with:
          dotnet-version: '6.0.x'

      - name: Build
        run: |
          dotnet build ${GITHUB_WORKSPACE}/SampleFunction/src/SampleFunction/SampleFunction.csproj
          (cd ${GITHUB_WORKSPACE}/SampleFunction/src/SampleFunction/bin/Debug/net6.0 && zip -r SampleFunction.zip .)

      - name: Deploy
        # デプロイ結果のoutputはターミナルに表示したくないため、いったんファイルに出力させてそのファイルをすぐ削除している
        run: |
          aws lambda update-function-code --function-name ${{ secrets.AWS_LAMBDA_FUNCTION_NAME }} --zip-file fileb://${GITHUB_WORKSPACE}/SampleFunction/src/SampleFunction/bin/Debug/net6.0/SampleFunction.zip --publish >> deploy.log
          rm deploy.log

ジョブの内容

ジョブのstepsを5段階に分けましたが、それぞれの内容を順を追って見ていきましょう。
今回使用する環境はubuntuとするため、job.deploy.runs-onにはubuntu-latestを指定します。

.github/workflows/lambda_deploy.yml
# 前後省略
jobs:
  deploy:
    runs-on: ubuntu-latest

checkout

デプロイ前にプログラムコードのビルドが必要であるため、checkoutしてジョブの実行環境にソースコードを持ってきます。
GitHub Actionsにはactions/checkoutアクションが用意されており、今回は最新のv3を使用します。(actions/checkout@v3

.github/workflows/lambda_deploy.yml
# 前後省略
jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v3

同じジョブのstep間のリソースは共有できるため、以降は別stepに分けて記述していきます。

AWS認証

今回はデプロイ先がAWS Lambdaであるため、デプロイ前にAWSユーザの認証が必要となります。
ルートユーザだと権限が強すぎるため、AWS IAMでLambda用のユーザを作成しておきます。
今回は、作成したユーザに「AWSLambda_FullAccess」「CloudWatchFullAccess」「CloudWatchEventsFullAccess」の許可ポリシーを割り当てております。(ユーザがLambdaへデプロイする権限があればカスタムの許可ポリシーなどでも良いです。)
参考:AWS アカウント での IAM ユーザーの作成

ユーザを作成したら、そのユーザのアクセスキーを発行します。作成したIAMユーザを選択して「アクセスキーを作成」から作成することが可能です。アクセスキーとシークレットアクセスキーを後ほど使うためためメモしておきましょう。

AWS認証は、専用のアクションaws-actions/configure-aws-credentialsが用意されているためこちらを使用します。
先ほど作成・メモしたアクセスキーとシークレットアクセスキーを使用するのですが、直接ymlファイルに記述してしまうとユーザ情報が外部に漏れてしまいます。漏洩を防ぐためGitHubのsecretsを使用します。
対象リポジトリで、Setting > Secrets and variables > Actionsと進みます。
キーの名前は任意で構いませんが、今回はアクセスキーをAWS_ACCESS_KEY_ID、シークレットアクセスキーをAWS_SECRET_ACCESS_KEYという名前でキーを登録します。
image.png
登録したキーをactionで使用します。
aws-actions/configure-aws-credentialsアクションでは、アクセスキー(aws-access-key-id)・シークレットアクセスキー(aws-secret-access-key)・Lambdaで使用するリージョン(aws-region)を指定する必要があり、それぞれ以下のように指定することでGitHub ActionsでAWSの認証ができます。

.github/workflows/lambda_deploy.yml
# 前後省略
jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - 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: ${{ secrets.AWS_REGION }}

.NET環境のセットアップ

actionで.NET環境を整えていきましょう。actions/setup-dotnetアクションで.NET環境の構築ができます。
今回.NETのバージョンは6.0系を使用しているため、dotnet-versionには'6.0.x'を指定します。

.github/workflows/lambda_deploy.yml
# 前後省略
jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - 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: ${{ secrets.AWS_REGION }}

      - name: Setup dotnet
        uses: actions/setup-dotnet@v3
        with:
          dotnet-version: '6.0.x'

プログラムコードのビルド

.NET環境のセットアップを行ったため、dotnet buildコマンドで.NETプロジェクトのビルドができます。
引数でプロジェクトファイルの指定が必要ですが、checkoutした際のcheckout先ディレクトリパスは${GITHUB_WORKSPACE}で取得できます。
参考:Learn GitHub Actions - Variables
環境のところでも記載したように、プロジェクトファイルはSampleFunction/src/SampleFunction/SampleFunction.csprojに存在するため、ビルド先のパスは${GITHUB_WORKSPACE}/SampleFunction/src/SampleFunction/SampleFunction.csproj指定とします。

またLambdaへのデプロイ時にはビルドしたものをzipファイルにして、zipファイルをデプロイしますが、zipコマンドを使用する際には一度bin/Debug/net6.0に移動してからzipファイルを作成します。
bin/Debug/net6.0に移動せずにzipファイルを作成すると、${GITHUB_WORKSPACE}直下のディレクトリからzipファイル化されてしまい、Lambdaにデプロイした際にエラーとなってしまいます。
参考:ディレクトリ内のファイルを zip ファイルにバックアップする

.NETプロジェクトをLambdaで動かすにはbin/Debug/net6.0配下をデプロイする必要があります。

.github/workflows/lambda_deploy.yml
# 前後省略
jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - 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: ${{ secrets.AWS_REGION }}

      - name: Setup dotnet
        uses: actions/setup-dotnet@v3
        with:
          dotnet-version: '6.0.x'

      - name: Build
        run: |
          dotnet build ${GITHUB_WORKSPACE}/SampleFunction/src/SampleFunction/SampleFunction.csproj
          (cd ${GITHUB_WORKSPACE}/SampleFunction/src/SampleFunction/bin/Debug/net6.0 && zip -r SampleFunction.zip .)

AWS Lambdaへデプロイ

いよいよLambdaへのデプロイです。
AWS CLIを使用できるため、aws lambda update-function-codeコマンドでLambda関数を更新します。(update-function-codeを使うには、AWS Lambdaの関数を事前に作成しておく必要があります。)
--function-nameで関数名を、--zip-fileで先ほど作成したzipファイルのパスを指定します。
ここで注意点です。コマンドが正常に実行されると、実行結果がJSON形式で表示されてしまいます。表示される実行結果の中には、環境変数やリージョンなど表示されたくない機密情報も表示されてしまいます。
publicリポジトリなどを使用している場合は、この情報がGitHub Actions上に表示されるのはあまりよろしくないため、>> deploy.logを付けて一度ファイルに出力してGitHub Actions上に表示されないようにしています。

.github/workflows/lambda_deploy.yml
# 前後省略
jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - 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: ${{ secrets.AWS_REGION }}

      - name: Setup dotnet
        uses: actions/setup-dotnet@v3
        with:
          dotnet-version: '6.0.x'

      - name: Build
        run: |
          dotnet build ${GITHUB_WORKSPACE}/SampleFunction/src/SampleFunction/SampleFunction.csproj
          (cd ${GITHUB_WORKSPACE}/SampleFunction/src/SampleFunction/bin/Debug/net6.0 && zip -r SampleFunction.zip .)

      - name: Deploy
        # デプロイ結果のoutputはターミナルに表示したくないため、いったんファイルに出力させてそのファイルをすぐ削除している
        run: |
          aws lambda update-function-code --function-name ${{ secrets.AWS_LAMBDA_FUNCTION_NAME }} --zip-file fileb://${GITHUB_WORKSPACE}/SampleFunction/src/SampleFunction/bin/Debug/net6.0/SampleFunction.zip --publish >> deploy.log
          rm deploy.log

このジョブが実行されると、AWSの画面上でもLambda関数が更新されることが確認できます。

プログラムコードが変更された時のみ自動デプロイする

ここまでのGitHub Actionsの状態では、リポジトリ内のすべてのファイルの変更に対してジョブが実行されてしまいます。しかし、README.mdやymlファイル自体の変更では、プログラムコードのビルド結果は変わりません。
そのため、プログラムコードの変更時のみビルド・デプロイを行いたいものです。(プログラムコード以外の変更ではジョブを実行しない。)
次のように、push以下にpaths-ignoreを定義することで特定ファイルのpush時にはジョブを実行しないようにすることが可能です。逆にpush以下にpathsを定義すると、特定ファイルのpush時のみジョブを実行することも可能です。

.github/workflows/lambda_deploy.yml
name: Deploy to AWS Lambda
on:
  push:
    branches:
      - master
    paths-ignore:
      # mdファイルやGitHub Actionsのフローyml、vscode設定ファイル関連はpushしてもジョブ実行しないようにする
      - '**/*.md'
      - '.gitignore'
      - '.github/**'
      - '.vscode/**'
jobs:
# 以下省略

参考

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