🤖

RDS の保留中のメンテナンスを GitHub Actions でチェック・適用する

2024/08/15に公開

備忘録程度のもの。

運用のイメージとしては以下。

  1. チェックワークフローを日次で起動して、RDS の保留中のメンテナンスがないかチェックする
  2. 1で RDS の保留中のメンテナンスがあれば、Slack へ通知される
  3. Slack へ通知された内容を確認し、問題なければ適用のワークフローで RDS の保留中のメンテナンスを適用する

チェック

内容としては至って簡単で、以下の通り。

  • aws rds describe-pending-maintenance-actions で保留中のメンテナンスを取得する
  • jq で加工して Slack 通知する
name: Check DB Maintenance

on:
  workflow_call:
  workflow_dispatch:

permissions:
  id-token: write

jobs:
  check-db-maintenance:
    runs-on: ubuntu-latest
    outputs:
      maintenance: ${{ steps.get-db-maintenance.outputs.maintenance }}
    steps:
      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          ... 省略 ...
      - name: Get DB Maintenance
        id: get-db-maintenance
        run: |
          echo "maintenance<<EOF" >> $GITHUB_OUTPUT
          echo "$(aws rds describe-pending-maintenance-actions | jq -r '.PendingMaintenanceActions[] | select(.PendingMaintenanceActionDetails[] | .OptInStatus == null or .CurrentApplyDate == null) | "\(.ResourceIdentifier)|\(.PendingMaintenanceActionDetails | map("\(.Action):\(.Description)") | join(","))"')" >> $GITHUB_OUTPUT
          echo "EOF" >> $GITHUB_OUTPUT

  slack-notification:
    needs: check-db-maintenance
    runs-on: ubuntu-latest
    if: ${{ needs.check-db-maintenance.outputs.maintenance != '' }}
    steps:
      - name: Send result to Slack
        run: |
          # ${{ needs.check-db-maintenance.outputs.maintenance }} には、メンテナンス情報が格納されている
          ... 省略 ...

上記ワークフローを以下の感じで定期的に実行させてあげると良い。

name: Check DB Maintenance Starter

on:
  schedule:
    - cron: '0 0 * * 1-5'

  workflow_dispatch:

permissions:
  id-token: write

jobs:
  check-db-maintenance-dev:
    name: Check DB Maintenance Dev
    uses: ./.github/workflows/check-db-maintenance.yaml
    secrets: inherit

適用

こちらもチェックで実装した内容とほぼ一緒。
違う点は、Slack 通知の部分が aws rds apply-pending-maintenance-actions で保留中のメンテナンスを適用しているところ。

はじめに示したチェックのワークフローの内容を確認して、問題ないことを確認したらこのワークフローで適用していくイメージ。

inputs で opt_in_type を指定できるようにしているが、immediate を指定すると即時反映され、DB が再起動されるので要注意。

name: Apply DB Maintenance

on:
  workflow_dispatch:
    inputs:
      opt_in_type:
        type: choice
        required: true
        default: "next-maintenance"
        description: |
          "next-maintenance": 次のメンテナンスウィンドウで適用,
          "immediate": 今すぐ適用
        options:
          - "next-maintenance"
          - "immediate"

permissions:
  id-token: write

jobs:
  check-db-maintenance:
    runs-on: ubuntu-latest
    outputs:
      maintenance: ${{ steps.get-db-maintenance.outputs.maintenance }}
    steps:
      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          ... 省略 ...
      - name: Get DB Maintenance
        id: get-db-maintenance
        run: |
          echo "maintenance<<EOF" >> $GITHUB_OUTPUT
          echo "$(aws rds describe-pending-maintenance-actions | jq -r '.PendingMaintenanceActions[] | "\(.ResourceIdentifier)|\(.PendingMaintenanceActionDetails | map(.Action) | join(","))"')" >> $GITHUB_OUTPUT
          echo "EOF" >> $GITHUB_OUTPUT

  apply-db-maintenance:
    needs: check-db-maintenance
    runs-on: ubuntu-latest
    if: ${{ needs.check-db-maintenance.outputs.maintenance != '' }}
    steps:
      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          ... 省略 ...
      - name: Apply DB Maintenance
        run: |
          while read line || [ -n "${line}" ]
          do
            IFS='|' read -r arn actions <<< "$line"
            IFS=',' read -ra action_array <<< "$actions"
            for action in "${action_array[@]}"; do
              echo "Apply db maintenance for $arn with action $action"
              aws rds apply-pending-maintenance-action \
                --resource-identifier "${arn}" \
                --apply-action "${action}" \
                --opt-in-type "${{ inputs.opt_in_type }}"
            done
          done <<< "${{ needs.check-db-maintenance.outputs.maintenance }}"

Discussion