GitHub ActionsワークフローでAmazon S3のオブジェクトにアクセスする

GitHub ActionsワークフローからAmazon S3オブジェクトにアクセスしたかったので、簡単なサンプルを作ってみました。
2020.02.26

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

とあるリポジトリで、GitHub ActionsワークフローのランナーからAmazon S3(以下、S3)にアクセスしたいニーズがありました。
簡単なサンプルを構築してみたので、ご紹介します。

手っ取り早くワークフローのYAMLを見たい方はこちらをどうぞ。
【GitHub】cm-mochida-atsushi/actions-python-sample

GitHub Actionsとは

GitHubが提供する高機能なCI/CD(継続的インテグレーション/継続的デリバリー)ツールです。
リモートリポジトリをGitHubで管理している場合、GitHub内でCI/CDを完結させることができます。
また、pushやpull requestだけでなくGitHub上の様々なアクティビティをトリガーにできます。

【GitHub ヘルプ】GitHub Actionsについて

なお、GitHub Actionsの料金は以下となっています。

  • パブリックリポジトリは 無料 で利用可能
  • プライベートリポジトリは、プランごとにストレージ・ジョブの実行時間に上限あり(追加料金を払うことで上限を超えても利用可能)

【GitHub ヘルプ】About billing for GitHub Actions

サンプルイメージ

今回のサンプルでは、GitHub Actionsのワークフロー内で、S3バケットにアクセスしてダウンロード/アップロードを実行させてみます。
ついでに、ワークフローでファイルの中身も出力させてみます。

事前準備

S3バケット・オブジェクトの準備

ワークフローからアクセスされる側のS3について、それぞれ以下のバケットを準備します。

  • ファイルダウンロード用バケット
  • ファイルアップロード用バケット

また、ファイルダウンロード用バケットに、以下の内容のテキストファイル sample.txt をアップロードしておきます。

sample.txt

hogehoge

IAMユーザーの準備

ワークフローからはAWS CLI経由でS3にアクセスするので、S3オブジェクトにアクセス可能なIAMユーザーを準備します。
また、対象のIAMユーザーのアクセスキーを取得しておいてください。

GitHub Secretsの設定

GitHub ActionsのワークフローはYAMLで定義されますが、YAMLにハードコーディングしたくない情報はGitHub Secretsに環境変数として登録しておきます。
(登録されたシークレットは暗号化されます)

【GitHub ヘルプ】Creating and storing encrypted secrets

ここでは、先程取得したアクセスキーとS3バケットを登録しています。

Name Value
AWS_ACCESS_KEY_ID (取得したIAMユーザーのアクセスキーID)
AWS_SECRET_ACCESS_KEY (取得したIAMユーザーのシークレットアクセスキー)
S3_DOWNLOAD_BUCKET (準備したファイルダウンロード用バケット名)
S3_UPLOAD_BUCKET (準備したファイルアップロード用バケット名)

GitHub Actions ワークフロー

それでは、実際にワークフローを定義していきます。

今回は develop ブランチへのpushをトリガーとし、以下の挙動となるようにステップを設定してみます。

  1. ダウンロード用S3バケットからファイルを取得する
  2. コンソールにファイルの中身を出力
  3. アップロード用S3バケットにファイルをアップロードする

.github/workflows/s3sample.yml

name: Amazon S3 Sample

on:
  push:
    branches:
      - develop

jobs:
  build:
    runs-on: ubuntu-latest
    timeout-minutes: 5

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

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

      - name: Download file from S3
        env: 
          S3_DOWNLOAD_BUCKET: ${{ secrets.S3_DOWNLOAD_BUCKET }}
        run: |
          aws s3 cp s3://$S3_DOWNLOAD_BUCKET/sample.txt ./  --quiet

      - name: Output file contents
        run: |
          cat ./sample.txt

      - name: Upload file to S3
        env: 
          S3_UPLOAD_BUCKET: ${{ secrets.S3_UPLOAD_BUCKET }}
        run: |
          aws s3 cp ./sample.txt s3://$S3_UPLOAD_BUCKET/ --quiet

GitHubホストランナー

今回はGitHubホストランナーとして ubuntu-latest(Ubuntu 18.04)を利用しています。

ホストランナーにはAWS CLIがデフォルトでインストールされているため、ワークフロー内でインストールせずともそのままAWS CLIを利用できます。便利!
(※2020/2/26時点、AWS CLIはv2ではなくv1がインストールされています)

また、GitHubホストランナーの仮想環境では、他にも様々なパッケージがデフォルトで利用可能となっています。
下記リンク先の Included Software から各環境に対するデフォルトパッケージが確認できます。

【GitHub】actions/virtual-environments

ジョブのタイムアウト設定

デフォルトではジョブのタイムアウトは360分となっていますが、予期せぬ長時間実行による浪費を防止するため、タイムアウトを5分に設定しています。

ステップの設定

ステップでは、まず Configure AWS credentials でアクセスキーなどAWSクレデンシャル情報の設定を行います。
こちらは、AWSが公開しているaws-actions/configure-aws-credentialsのアクションを利用しています。 クレデンシャル情報には、GitHub Secretsで登録したアクセスキーを変数として設定します。

その後の以下のステップでは、AWS CLIコマンドを使ってS3オブジェクトのダウンロード/アップロードおよびファイル内容の出力を行っています。

  • Download file from S3
  • Output file contents
  • Upload file to S3

ワークフローの実行

それでは、実際にワークフローを実行させてみましょう。
今回は develop ブランチで先程定義した.github/workflows/s3sample.ymlのpushを行い、そのままワークフローを走らせてみます。

push後、リポジトリの Actionsタブから対象のワークフローを選択します。
無事に Amazon S3 Sample が実行されていますね。

結果を確認すると、各ステップも問題なく実行されジョブは成功しています!

ダウンロードしたテキストファイルの内容も表示されていますね。

参考までに、Secretsの情報は実行結果の画面ではマスクされています。

最後に、ファイルアップロード用バケットを確認すると、きちんとファイルがアップロードされています!

おわりに

GitHub ActionsワークフローでAmazon S3にアクセスする簡単なサンプルを作ってみました。
やはり、GitHubに統合されているとCI/CDを構築しやすくていいですね。

どなたかの参考になれば幸いです。