🏋️

AWS SSM Send-Command を使用して GitHub Actions から EC2 インスタンスを操作する方法

2024/08/09に公開

最初に

GitHub Actions から EC2 インスタンスを操作したかったので、Send-Command を試しに使ってみました。

AWS SSM Send-Command とは

AWS Systems Manager の Send-Command 機能は、EC2 インスタンスにリモートでコマンドを実行するためのサービスです。
これにより、SSH 接続をせずにインスタンスを管理・操作することができます。
例えば、システムのアップデートやログの収集、アプリケーションのデプロイなどが可能です。

CloudFormation でロールを作成する

AWS CloudFormation を使用して、必要な IAM ロールを作成します。
このロールには AssumeRoleWithWebIdentity と SendCommand のポリシーと、
AWS リソースにアクセスするために必要な OIDC プロバイダーを設定します。

以下は、CloudFormation テンプレートの例です。

AWSTemplateFormatVersion: 2010-09-09

Parameters:
  Thumbprint1:
    Type: String
    Default: '6938fd4d98bab03faadb97b34396831e3780aea1'
  Thumbprint2:
    Type: String
    Default: '1c58a3a8518e8759bf075b76b750d4f2df264fcd'

Resources:
  GitHubActionsOidcProvider:
    Type: AWS::IAM::OIDCProvider
    Properties:
      Url: https://token.actions.githubusercontent.com
      ClientIdList:
        - sts.amazonaws.com
      ThumbprintList:
        - !Ref Thumbprint1
        - !Ref Thumbprint2
  RoleGitHubActions:
    Type: AWS::IAM::Role
    Properties:
      RoleName: github-actions-role
      AssumeRolePolicyDocument:
        Statement:
          - Effect: Allow
            Principal:
              Federated: !Sub arn:aws:iam::${AWS::AccountId}:oidc-provider/token.actions.githubusercontent.com
            Action: sts:AssumeRoleWithWebIdentity
            Condition:
              StringEquals:
                token.actions.githubusercontent.com:aud: sts.amazonaws.com
              StringLike:
                token.actions.githubusercontent.com:sub: "repo:xxx:*"
      Policies:
        - PolicyName: ssm-send-command
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - ssm:SendCommand
                Resource:
                  - arn:aws:ssm:ap-northeast-1:*:document/AWS-RunShellScript
                  - !Sub arn:aws:ec2:ap-northeast-1:${AWS::AccountId}:instance/*

GitHubActionsOidcProvider

GitHub Actions が AWS リソースにアクセスするために必要な OIDC プロバイダーを定義しています。
このリソースは、GitHub Actions が発行する OIDC トークンを使用して AWS に認証するために使用されます。

RoleGitHubActions

GitHub Actions が特定の AWS リソースに対して操作を行うための IAM ロールを定義しています。
このロールには、GitHub Actions がこのロールを引き受けるためのポリシーと、特定のアクションを許可するポリシーが含まれています。

このテンプレートを CloudFormation にデプロイすることで、GitHub Actions が使用できる IAM ロールを作成します。

GitHub Actions で実行

次に、GitHub Actions を使用して、実際に EC2 インスタンスにコマンドを送信します。
以下は、そのための GitHub Actions ワークフローファイルの例です

name: ssm-send-command-test

on:
  workflow_dispatch:
  push:
    branches:
      - main
    paths:
      - .github/workflows/actions.yaml
      - 'send-command-test/**'

permissions:
  id-token: write
  contents: read

jobs:

  send-command-test:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repo
        uses: actions/checkout@v4

      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v2
        with:
          role-to-assume: "arn:aws:iam::MY_ACCOUNT_ID:role/github-actions-role"
          aws-region: ap-northeast-1
      - name: AWS Systems Manager Run Command
        run: |
          aws ssm send-command \
            --document-name 'AWS-RunShellScript' \
            --instance-ids 'i-XXXXXXX' \
            --parameters 'commands=[
              "bash -c \"touch ssm-send-command-test.txt\""
            ]' \
            --timeout-seconds 60 \
            --region ap-northeast-1

このワークフローは、以下のステップを実行します:

  1. リポジトリをチェックアウトします。
  2. aws-actions/configure-aws-credentials を使用して AWS 認証情報を設定します。
  3. aws ssm send-command を使用して、指定された EC2 インスタンスにコマンドを送信します。
    ※MY_ACCOUNT_ID は自身の AWS アカウント ID を入れてください
    ※instance-ids は EC2 インタスタンス ID を入れてください

結果

EC2 インスタンスに Session Manager で接続し、ファイルが生成されていることを確認します。

$ ls -la
total 8
drwxr-xr-x 2 root root 4096 Aug  5 00:21 .
drwxr-xr-x 5 root root 4096 Jul 31 10:03 ..
-rw-r--r-- 1 root root    0 Aug  5 00:26 ssm-send-command-test.txt

成功です🙌

最後に

今回はファイルを PUSH した後に GitHub Actions で EC2 インスタンスへ PUSH したファイルを配置したかったので、Send-Command を試しに使ってみました。

これを活用することで、手動で配置したりする手間を省略できたり、複数のインスタンスへ同時へ操作するということも可能で、運用の効率化に繋がると思います😀

レスキューナウテックブログ

Discussion