0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

GitHubActionsでAWSのセキュリティグループのルールを一時的に変更する

Posted at

経緯

GitHubActionsのワーカーから、AWSのEC2にSSHで接続したい!

GitHubActionsのワーカーのグローバルIPアドレスでのSSH接続をEC2のセキュリティグループで許可しよう

GitHub無料利用だと、クラウド上のワーカー(AzureのVMらしい)となり、ワーカーが作成されるたびに異なるIPアドレスが割り当てられることを知る

セキュリティグループの設定に必要な固定のIPアドレスがわからない!

割り当てられるIPアドレスのリストは公開されているが、実際に使用するIPアドレスだけ許可したい...

今に至る

解決策

下記の3点で、対応可能
詳細を事項で解説

① 作成されたワーカー内で、現在のグローバルIPアドレスを取得する

② AWS CLIでセキュリティグループにポート22, 取得したIPアドレスでルールを追加

③ ジョブの最後でルールを削除

必要作業

大まかに必要な作業を列挙する

① GitHubとAWSをOIDCで認証するように設定 (GitHubドキュメント)

アクセスキー・シークレットキーでも可能だが、キーの運用の手間やセキュリティの観点からOIDCを使うことにする

AWSのIAMコンソールからIDプロバイダを設定する

下記項目を選択・入力してプロバイダを追加
プロパティのタイプ:OpenID Connect
プロバイダのURL:https://token.actions.githubusercontent.com
対象者:sts.amazonaws.com
image.png

② OIDC用のIAMロール作成とポリシーの追加

OIDC用のロールを作成し、ワーカーが実際にセキュリティグループに対してアクションが可能なポリシーを追加する

ロールの作成

AWSアカウントID、GitHubのユーザ名、リポジトリ名を適宜設定
ちなみに、今回はリポジトリ名の後はワイルドカードで指定しているがブランチも指定が可能

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Allow",
            "Principal": {
                "Federated": "arn:aws:iam::<AWSアカウントID>: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:<GitHubユーザ名>/<リポジトリ名>:*"
                }
            }
        }
    ]
}

ポリシーの作成・アタッチ

※ロールの詳細画面からインラインポリシーを作成してもよし、作成したポリシーをロールにアタッチするもよし

ルールの作成、削除とルール一覧を表示するポリシーを付与
リージョン、AWSアカウントID、セキュリティグループIDを適宜入力

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "ec2:RevokeSecurityGroupIngress",
                "ec2:AuthorizeSecurityGroupIngress"
            ],
            "Resource": "arn:aws:ec2:<リージョン>:<AWSアカウントID>:security-group/<セキュリティグループID>"
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": "ec2:DescribeSecurityGroupRules",
            "Resource": "*"
        }
    ]
}

③ ジョブ内容(ymlファイル)作成

今回はSSH接続方法までは解説せず、あくまでセキュリティグループへのルールの追加・削除方法を記載する
ちなみに今回はAWS CLIを使うが、SDKを利用したプログラミング言語でも可能

最終的なコードは最後に表示するとして、要点の部分を記載していく

アクセス許可設定

permissions:
  id-token: write   # id-tokenは「write」を指定(これ絶対)
  contents: read    

アクセストークンの要求

 - name: AWS CLI set up
        uses: actions/checkout@v4
 - name: configure aws credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-session-name: Hoge
          role-to-assume: ${{ secrets.AWS_IAM_ROLE_ARN }} # ②で作成したロールのARNを指定
          aws-region: <リージョン>

IPアドレスを取得してセキュリティグループにルールを追加

 - name: add tempolary securitygroup rule
   run: | 
          WORKER_IP=$(curl -s https://checkip.amazonaws.com/)  # グローバルIPアドレスを返すAPIエンドポイント
          aws ec2 authorize-security-group-ingress --group-id ${{ secrets.AWS_SECURITY_GROUP_ID }} --protocol tcp --port 22 --cidr $WORKER_IP/32

追加したルールの削除

ルール追加時に取得したWORKER_IPのスコープは狭いため、削除時には再度取得する必要アリ

 - name: revoke tempolary securitygroup rule
        run: |
          WORKER_IP=$(curl -s https://checkip.amazonaws.com/)
          aws ec2 revoke-security-group-ingress --group-id ${{ secrets.AWS_SECURITY_GROUP_ID }} --protocol tcp --port 22 --cidr $WORKER_IP/32

全体のコード

※一部マスクしてます

name: Build Test

on:
  push:
    branches:
      - deploy  # 実行対象のブランチを指定
  workflow_dispatch:
  
permissions:
  id-token: write   
  contents: read    
  
jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      # コードのチェックアウト
      - name: Checkout Code
        uses: actions/checkout@v4

      - name: AWS CLI set up
        uses: actions/checkout@v4
      - name: configure aws credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-session-name: ******
          role-to-assume: ${{ secrets.AWS_IAM_ROLE_ARN }}
          aws-region: *******
      

      - name: update tempolary securitygroup rule
        run: | 
          WORKER_IP=$(curl -s https://checkip.amazonaws.com/)
          aws ec2 authorize-security-group-ingress --group-id ${{ secrets.AWS_SECURITY_GROUP_ID }} --protocol tcp --port 22 --cidr $WORKER_IP/32

      - name: SSH and clone app on EC2
        run: |
          sudo apt update -y && sudo apt install -y openssh-client
          sudo mkdir -p /home/runner/.ssh
          sudo chmod 700 /home/runner/.ssh
          sudo echo "${{ secrets.AWS_EC2_PRIVATE_KEY }}" | sudo tee /home/runner/.ssh/id_rsa > /dev/null
          sudo chmod 600 /home/runner/.ssh/id_rsa
          sudo ssh -i /home/runner/.ssh/id_rsa -o StrictHostKeyChecking=no ubuntu@****** "sudo rm -rf /var/next-arc"
          sudo ssh -i /home/runner/.ssh/id_rsa -o StrictHostKeyChecking=no ubuntu@****** 'sudo GIT_SSH_COMMAND="ssh -i /root/.ssh/id_rsa" git clone git@github.com:******/******.git /var/next-arc'
          sudo ssh -i /home/runner/.ssh/id_rsa -o StrictHostKeyChecking=no ubuntu@****** 'sudo touch /var/next-arc/.env && sudo chmod 666 /var/next-arc/.env && \
          sudo echo "${{ secrets.NEXT_PUBLIC_BACKEND_URL }}" >> /var/next-arc/.env && \
          sudo echo "${{ secrets.THUMBNAIL_IMAGE_PATH }}" >> /var/next-arc/.env && \
          sudo echo "${{ secrets.BACKEND_APP_PATH }}" >> /var/next-arc/.env'
          
      - name: build and start app
        run: |
          sudo ssh -i /home/runner/.ssh/id_rsa -o StrictHostKeyChecking=no ubuntu@****** "cd /var/next-arc"
          sudo ssh -i /home/runner/.ssh/id_rsa -o StrictHostKeyChecking=no ubuntu@****** 'sudo bash -c "cd /var/next-arc && \
          npm install && \
          npm run build && \
          pm2 delete all && \
          pm2 start npm --name \"next\" -- start && \
          pm2 save"'
          
      - name: revoke tempolary securitygroup rule
        run: |
          WORKER_IP=$(curl -s https://checkip.amazonaws.com/)
          aws ec2 revoke-security-group-ingress --group-id ${{ secrets.AWS_SECURITY_GROUP_ID }} --protocol tcp --port 22 --cidr $WORKER_IP/32
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?