kasei_sanのブログ

かせいさんのIT系のおぼえがきです。胡乱の方はnoteとtwitterへ

GitHub Actions で Action に失敗した時にslackに通知を投げる方法

先に方法

    - name: Slack Notification when build failed
      if: failure()
      uses: rtCamp/action-slack-notify@master
      env:
        SLACK_CHANNEL: channel-name
        SLACK_COLOR: '#ff0000'
        SLACK_TITLE: ':fire::fire::fire: Build error! :fire::fire::fire:'
        SLACK_MESSAGE: "Build error! Please check github!"
        SLACK_USERNAME: GitHub Actions
        SLACK_WEBHOOK: ${{secrets.SLACK_WEBHOOK}}

実行結果

f:id:kasei_san:20200310184843p:plain

解説

参考

tech.actindi.net

GitHub Actions で削除したブランチ名を取得する方法

課題

GitHub Actionsでは、ブランチ名は環境変数 GITHUB_REF から取ることができるが、ブランチ削除時には GITHUB_REFrefs/heads/master になってしまう

  • なお、GitHub Actions で使用できる環境変数については、こちらを参照

help.github.com

解決方法

${{ github.event.ref }} から取得する

github.event とは

webhook event のペイロードがすべて格納されているところ

ブランチ削除の場合のペイロードはこちらを参照

参考

検証コード

name: delete_branch

on: [delete]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - name: Echo branch name
      run: echo ${GITHUB_REF}
    - name: Echo commit hash
      run: echo ${GITHUB_SHA}
    - name: Echo github.event.ref
      run: echo "${{ github.event.ref }}"

GitHub Actions から AWS lambda を実行してみる

こちらのつづき

blog.kasei-san.com

GitHub Actions から AWS lambda を実行するまでの流れ

  • lambdaを作成
  • lambdaの実行権限を持つIAMユーザを作成
  • AWS認証の action aws-actions/configure-aws-credentials を GitHub Actions に組み込む
  • 認証に使用する、lambdaの実行権限を持つIAMユーザの各キーを secrets に設定
  • 実行

lambdaを作成

"hello" を puts するだけのシンプルな lambda hellous-east-1 に作成

require 'json'

def lambda_handler(event:, context:)
    # TODO implement
    
    puts 'hello'
    
    { statusCode: 200, body: JSON.generate('Hello from Lambda!') }
end

lambdaの実行権限を持つIAMユーザを作成

IAMユーザ github-actions を作成

$ aws iam create-user --user-name github-actions
{
    "User": {
        "Path": "/",
        "UserName": "github-actions",
        "UserId": "********",
        "Arn": "arn:aws:iam::********:user/github-actions",
        "CreateDate": "2020-03-03T05:02:59Z"
    }
}

github-actions に lambda実行権限持つロールを付与

$ aws iam attach-user-policy \
  --user-name github-actions \
  --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaRole

ローカルで動作確認

$ aws lambda invoke --function-name hello --region us-east-1 response.json
{
    "StatusCode": 200,
    "ExecutedVersion": "$LATEST"
}

AWS認証の action aws-actions/configure-aws-credentials を GitHub Actions に組み込む

aws-actions/configure-aws-credentials は AWS 公式の github action

Configure AWS credential and region environment variables for use in other GitHub Actions.

github.com

こんなふうに、アクセスキーとシークレットキーとリージョンを設定してやれば、ユーザの権限に応じた、AWS CLI が使えるようになる

name: CI
on: [push]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - 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: us-east-1
    - name: Run a one-line script
      run: echo Hello, world!
    - name: Run a multi-line script
      run: |
        echo Add other actions to build,
        echo test, and deploy your project.

認証に使用する、各キーを secrets に設定

GitHub Actionsで使用したい秘匿情報は、secrets に設定して、そこから取得する

アクセスキーを取得

$aws iam create-access-key --user-name github-actions


{
    "AccessKey": {
        "UserName": "github-actions",
        "AccessKeyId": "********",
        "Status": "Active",
        "SecretAccessKey": "********",
        "CreateDate": "2020-03-03T05:03:23Z"
    }
}

アクセスキーを github の secrets に設定

secrets に設定することで、GitHub Actions にて ${{ secrets.key_name }} で参照できるようになる

settings -> secrets で設定可能

f:id:kasei_san:20200304175044p:plain

ここに、AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY を設定する

f:id:kasei_san:20200304175206p:plain

実行

lambdaを実行する処理をstepに追加する

name: CI
on: [push]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - 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: us-east-1
    - name: Run a hello lambda
      run: aws lambda invoke --function-name hello response.json

動作確認

コードをPUSHして、GitHub Actions から lambda が実行されて、正常終了の結果が返ってきたことを確認 👏

f:id:kasei_san:20200304175342p:plain

GitHub Actions はじめの一歩

GitHub Actions とは

GitHub の特定のアクションをトリガーにCI/CD的なことを実行できるサービス

  • CircleCI とか AWS Codebuild みたいのを GitHub が提供してくれるようになった

help.github.com

アクションのつくりかた

Githubのリポジトリから「Actions」を選択

いろんなActionをサジェストしてくれるけど、今回は Simple workflow を選択

f:id:kasei_san:20200304163103p:plain

すると、 .github/workflows/blank.yml にファイルが生成される

f:id:kasei_san:20200304163516p:plain

name: CI
on: [push]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - name: Run a one-line script
      run: echo Hello, world!
    - name: Run a multi-line script
      run: |
        echo Add other actions to build,
        echo test, and deploy your project.

設定ファイルの構文

公式ドキュメントを参照

help.github.com

ざっくりこんなかんじ

  • name : 名前
  • on : 発火するイベント
  • jobs : イベント発火時に実行する処理を格納するところ
  • jobs.<job_id> : イベント発火時に実行する処理。<job_id> は build
  • jobs.<job_id>.runs-on : 実行環境。windowsとかMacOSもある
  • jobs.<job_id>.steps : 実行する処理
  • jobs.<job_id>.uses : ジョブのステップの一部として実行される外部のアクション。公開リポジトリなどを参照できる。今回の場合 https://github.com/actions/checkout が実行される
  • jobs.<job_id>.name githubに表示されるステップの名前
  • jobs.<job_id>.run ステップで実行される処理。runs-on で指定したOSでコマンドラインが実行される

アクションを実行してみる

コードを commit すると早速アクションが実行される

実行結果

f:id:kasei_san:20200304164746p:plain

step単位で処理が実行されているのが分かる

感想

  • 他サービスを使わずにGitHub上でCIまでまとめて実行できるのは良い感じに思える
  • 今の会社だと、CIにAWS CodeBuildを使っているが、private VPCでビルドする必然性がなければ、GitHub Actionsに移行した方が管理がシンプルになってよいのかもしれない
  • PRとの連携も、他のサービス使うより楽そう(な気がする

ざっくりそんなかんじ

httpのレスポンスの動作確認をしたい時に知ってると便利ないろいろ

httpstat.us

httpstat.us

http://httpstat.us/${コード} で任意のレスポンスコードを返してくれるサービス

こんなかんじ

$ curl -I https://httpstat.us/200
HTTP/1.1 200 OK
$ curl -I https://httpstat.us/404
HTTP/1.1 404 Not Found

どうやら個人で作っているサイトなので CI とかに組み込むのはやめておいたほうが良いかも

http://ozuma.sakura.ne.jp/httpstatus/

ozuma.sakura.ne.jp

こちらも個人制作の任意のレスポンスコードを返してくれるサービス

$ curl -I https://ozuma.sakura.ne.jp/httpstatus/404
HTTP/2 404 

.invalid

RFC2606 で定義されている、無効なドメイン

digすると、NXDOMAIN が返ってくる

 $ dig example.invalid

; <<>> DiG 9.10.6 <<>> example.invalid
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 9629
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1

確実に存在しないので、そういう動作確認をしたい時に便利

AWS SDK for Ruby で Application Load Balancer にいろいろな Listener を追加する方法おぼえがき

Listenerとは

リスナーとは、設定したプロトコルとポートを使用して接続リクエストをチェックするプロセスです。リスナーに対して定義したルールにより、ロードバランサーが登録済みターゲットにリクエストをルーティングする方法が決まります。

Application Load Balancer のリスナー - Elastic Load Balancing

80番ポートのリクエストを443番ポートにリダイレクトする

client = Aws::ElasticLoadBalancingV2::Client.new
client.create_listener(
  default_actions: [
    {
      type: 'redirect',
      order: 1,
      redirect_config: {
        protocol: 'HTTPS',
        port: '443',
        host: '#{host}',
        path: '/#{path}',
        query: '#{query}',
        status_code: 'HTTP_301'
      }
    },
  ],
  load_balancer_arn: LOAD_BALANCER_ARN,
  port: 80,
  protocol: 'HTTP'
)

443番ポートのリクエストを特定のターゲットグループに渡す

client.create_listener(
  certificates: [
    certificate_arn: CERTIFICATE_ARN,
  ],
  default_actions: [
    {
      target_group_arn: TARGET_GROUP_ARN,
      type: 'forward'
    },
  ],
  load_balancer_arn: LOAD_BALANCER_ARN,
  port: 443,
  protocol: 'HTTPS',
  ssl_policy: 'ELBSecurityPolicy-2015-05'
)

443番ポートのリクエストの場合503を返す

client.create_listener(
  certificates: [
    certificate_arn: CERTIFICATE_ARN,
  ],
  default_actions: [
    {
      type: 'fixed-response',
      fixed_response_config: {
        status_code: '503'
      }
    },
  ],
  load_balancer_arn: LOAD_BALANCER_ARN,
  port: 443,
  protocol: 'HTTPS',
  ssl_policy: 'ELBSecurityPolicy-2015-05'
)
  • status_code の値は数字ではなく文字列

参考

公式ドキュメント

serverless で AWS lambda のログ出力の有効期限を制御する方法

サンプル

function hoge_fuga-aaa の出力先ロググループの有効期限を30日にする場合

serverless.yml

functions:
  hoge_fuga-aaa:
    handler: handler.api_create
    events:
      - http:
          path: api/create
          method: post
resources:
  Resources:
    HogeUnderscoreFugaDashAaaLogGroup:
      Properties:
        RetentionInDays: "30"
  • resources は serverless が使用する CloudFormationリソースを上書きする設定
  • 特定の function のロググループは、#{function名をアッパーケースにした文字列}LogGroup で定義される
    • このとき -Dash に、_Underscore に変換されるので注意
  • PropertiesRetentionInDays を設定すれば、有効期限が設定される
    • デフォルトでは有効期限なし

参考

公式の解説

https://github.com/serverless/serverless/blob/master/docs/providers/aws/guide/resources.md#override-aws-cloudformation-resource