📤

GitHub Actionsのファイルパーミッション周りでのエラーの解消方法

2021/10/22に公開

概要

GitHub ActionsでSAMを用いてデプロイしようとした際に、パッケージ管理ツールを使用して取得したファイルのパーミッションがrootになっていて読み込みできなくなっていた事象があったので、その対処について書き留めておきます。
結論から言いますと、GitHub Actionsのworkflow内でchownすると解決します。

動かないworkflowのyamlファイル

on:
  push:
    branches:
      - deploy/dev-lambda
jobs:
  s3upload-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: ruby/setup-ruby@v1
      - uses: actions/cache@v2
        with:
          path: vendor/bundle
          key: ${{ runner.os }}-dev-gems-${{ hashFiles('**/Gemfile.lock') }}
      - uses: aws-actions/setup-sam@v1
      
      - uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ secrets.DEV_AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.DEV_AWS_SECRET_ACCESS_KEY }}
          aws-region: ap-northeast-1

      - name: bundle install from docker image
        run: docker run -v `pwd`:`pwd` -w `pwd` amazon/aws-sam-cli-build-image-ruby2.7 bundle install --path vendor/bundle
        
      - name: packaging artifact to S3
        run: sam package --template-file template.yaml --region ap-northeast-1 --output-template-file packaged-template.yaml --s3-bucket xxxxxxxxxxxxxxx-s3-bucket

事象

GitHub ActionsからAWS Lambdaへの自動デプロイを行う際に、必要なパッケージをdockerイメージ(amazon/aws-sam-cli-build-image-ruby2.7)を用いてbundle installしています。取得データは./vendor/bundleディレクトリに置かれます。
以下のコマンドはすべてGitHub Actionsのworkflow内で実行されています。

docker run -v `pwd`:`pwd` -w `pwd` amazon/aws-sam-cli-build-image-ruby2.7 bundle install --path 

上で得られたファイルも含めてSAMを用いて以下のコマンドでs3にuploadしようとしました。

sam package --template-file template.yaml --region ap-northeast-1 --output-template-file packaged-template.yaml --s3-bucket xxxxxx-s3-bucket

その際に、以下のようなエラーが出てしまいました

Error: Unable to upload artifact ./ referenced by CodeUri parameter of RailsFunction resource.
[Errno 13] Permission denied: '/home/runner/work/xxxxxxxxxxxx/xxxxxxxxxxxx/vendor/bundle/ruby/2.7.0/gems/net-sftp-3.0.0/net-sftp-public_cert.pem'
Error: Process completed with exit code 1.

どうやら、dockerを経由したbundle installで取得したファイルの中に、read権限がついていない物があるようです。
そもそも同じユーザで実行していそうなのに何故read権限がないのか。調査をしてみました

調査

GitHub Actionsのworkflowのyamlファイル内でwhoamils -lコマンドを実行して原因を調査します。

on:
  push:
    branches:
      - deploy/dev-lambda
jobs:
  s3upload-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: ruby/setup-ruby@v1
      
      - name: whoami
        run: whoami

      - name: bundle install from docker image
        run: docker run -v `pwd`:`pwd` -w `pwd` amazon/aws-sam-cli-build-image-ruby2.7 bundle install --path vendor/bundle
    
      - name: ls lha
        run: ls -lha /home/runner/work/xxxxxxx/xxxxxxxxxx/vendor
	
      - name: ls lha
        run: ls -lha /home/runner/work/xxxxxxx/xxxxxxxxxx/vendor/bundle/ruby/2.7.0/gems/net-sftp-3.0.0/net-sftp-public_cert.pem

workflow実行結果

whoami

runner

ls -lha /home/runner/work/xxxxxxx/xxxxxxxxxx/vendor

drwxr-xr-x  3 runner docker 4.0K Oct 20 10:19 .
drwxr-xr-x 15 runner docker 4.0K Oct 20 10:21 ..
-rw-r--r--  1 runner docker    0 Oct 20 10:19 .keep
drwxr-xr-x  3 runner docker 4.0K Oct 20 10:10 bundle

ls -lha /home/runner/work/xxxxxxx/xxxxxxxxxx/vendor/bundle/ruby/2.7.0/gems/net-sftp-3.0.0/net-sftp-public_cert.pem

-rw------- 1 root root 1.2K Oct 20 10:10 /home/runner/work/xxxxxxx/xxxxxxxxxx/vendor/bundle/ruby/2.7.0/gems/net-sftp-3.0.0/net-sftp-public_cert.pem

原因と結論

というわけで、net-sftp-public_cert.pem だけが何故かroot:root権限で取得されていることがわかりました。
今回のtaskでrootである必要は無いので以下のようにchownするstepをworkflowに追加してあげました。

- name: change owner of vender directory(some files owner is root)
  run: sudo chown -R runner:docker /home/runner/work/xxxxxxx/xxxxxxxxxx/vendor

これで無事artifactをs3にアップロードすることが出来ました。
参考までにRailsで作られたLambdaをGitHub Actionsを使用してデプロイするためのworkflowのyamlファイルを書いておきます。

on:
  push:
    branches:
      - deploy/dev-lambda
jobs:
  s3upload-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: ruby/setup-ruby@v1
      - uses: actions/cache@v2
        with:
          path: vendor/bundle
          key: ${{ runner.os }}-dev-gems-${{ hashFiles('**/Gemfile.lock') }}
      - uses: aws-actions/setup-sam@v1
      
      - uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ secrets.DEV_AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.DEV_AWS_SECRET_ACCESS_KEY }}
          aws-region: ap-northeast-1

      - name: put tmp/development_secret.txt
        run: echo ${{ secrets.DEVELOPMENT_SECRET_FILE }} >> tmp/development_secret.txt
        shell: bash

      - name: bundle install from docker image
        run: docker run -v `pwd`:`pwd` -w `pwd` amazon/aws-sam-cli-build-image-ruby2.7 bundle install --path vendor/bundle
    
      - name: change owner of vender directory(some files owner is root)
        run: sudo chown -R runner:docker /home/runner/work/xxxxxxxxxxxxxxx/xxxxxxxxxxxxxxx/vendor
        
      - name: packaging artifact to S3
        run: sam package --template-file template.yaml --region ap-northeast-1 --output-template-file packaged-template.yaml --s3-bucket xxxxxxxxxxxxxxx-s3-bucket

      - name: deploy package to Lambda from S3
        run: sam deploy --template-file packaged-template.yaml --region ap-northeast-1 --stack-name xxxxxxxx-stack --capabilities CAPABILITY_NAMED_IAM --parameter-overrides Environment=development

Discussion