Skip to content
Ivan Dyachkov edited this page Jul 31, 2024 · 2 revisions

Keep ephemeral runner instance up after the job has finished

In short: adding ghr:keep => true tag on an instance will prevent the automatic shutdown and cleanup. But don't forget to cleanup.

First step is to get instance id from the "Set up job" section of the workflow run. You should see Runner name: 'ci_i-015b44c96190c0188' line, and instance id in this case is i-015b44c96190c0188. You will also need a Session Manager AWS CLI plugin to connect to instance.

export instance_id=i-015b44c96190c0188
aws ec2 create-tags --resources $instance_id --tags 'Key=ghr:keep,Value=true'
aws ssm start-session --target $instance_id
Starting session with SessionId: <user>-<id>
$ sudo -i
root@ip-<...>:~#
<...>
root@ip-<...>:~# ^D
Exiting session with sessionId: <user>-<id>.

aws ec2 terminate-instances --instance-ids $instance_id

Spin up test runner instance

amd64

AMI_ID=$(aws ec2 describe-images \
  --filters 'Name=name,Values=github-runner-amd64-*' \
  --query 'sort_by(Images, &CreationDate)[0].ImageId' \
  --output text)
SUBNET_ID=$(aws ec2 describe-subnets \
  --filters 'Name=tag:Env,Values=ci' 'Name=mapPublicIpOnLaunch,Values=true' \
  --query 'Subnets[0].SubnetId' \
  --output text)
SECURITY_GROUP_ID=$(aws ec2 describe-security-groups \
  --filters 'Name=tag:Name,Values=ci-linux-x64-action-runner' \
  --query 'SecurityGroups[0].GroupId' \
  --output text)
INSTANCE_ID=$(aws ec2 run-instances \
  --image-id $AMI_ID \
  --instance-type m7i.large \
  --block-device-mappings '[{"DeviceName":"/dev/xvda","Ebs":{"VolumeSize":30,"VolumeType":"gp3","DeleteOnTermination":true}}]' \
  --count 1 \
  --subnet-id $SUBNET_ID \
  --security-group-ids $SECURITY_GROUP_ID \
  --iam-instance-profile Name=ci-linux-x64-runner-profile \
  --query 'Instances[0].InstanceId' \
  --output text \
  --user-data '#!/bin/bash
mkfs.xfs -f -L data /dev/nvme1n1
mkdir -p /data
mount -L data /data
mkdir -p /data/docker
chown -R root:docker /data/docker
systemctl restart docker.service'
)
aws ec2 wait instance-status-ok --instance-ids $INSTANCE_ID

arm64

AMI_ID=$(aws ec2 describe-images \
  --filters 'Name=name,Values=github-runner-arm64-*' \
  --query 'sort_by(Images, &CreationDate)[0].ImageId' \
  --output text)
SUBNET_ID=$(aws ec2 describe-subnets \
  --filters 'Name=tag:Env,Values=ci' 'Name=mapPublicIpOnLaunch,Values=true' \
  --query 'Subnets[0].SubnetId' \
  --output text)
SECURITY_GROUP_ID=$(aws ec2 describe-security-groups \
  --filters 'Name=tag:Name,Values=ci-linux-arm64-action-runner' \
  --query 'SecurityGroups[0].GroupId' \
  --output text)
INSTANCE_ID=$(aws ec2 run-instances \
  --image-id $AMI_ID \
  --instance-type m7g.large \
  --block-device-mappings '[{"DeviceName":"/dev/xvda","Ebs":{"VolumeSize":30,"VolumeType":"gp3","DeleteOnTermination":true}}]' \
  --count 1 \
  --subnet-id $SUBNET_ID \
  --security-group-ids $SECURITY_GROUP_ID \
  --iam-instance-profile Name=ci-linux-arm64-runner-profile \
  --query 'Instances[0].InstanceId' \
  --output text \
  --user-data '#!/bin/bash
mkfs.xfs -f -L data /dev/nvme1n1
mkdir -p /data
mount -L data /data
mkdir -p /data/docker
chown -R root:docker /data/docker
systemctl restart docker.service'
)
aws ec2 wait instance-status-ok --instance-ids $INSTANCE_ID

Connecting to the instance

aws ssm start-session --target $INSTANCE_ID
$ sudo -i
<...>

Cleanup

aws ec2 terminate-instances --instance-ids $INSTANCE_ID