日々のいろいろ

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

投稿日: 5/7/2025

経緯

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

画像

② 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 / 1500 文字