Skip to content

Commit bf321ec

Browse files
committed
chore: create a script to resize using boto3
1 parent 0df3526 commit bf321ec

File tree

2 files changed

+107
-29
lines changed

2 files changed

+107
-29
lines changed

.github/workflows/testinfra-nix.yml

Lines changed: 12 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -53,37 +53,20 @@ jobs:
5353
GIT_SHA=${{github.sha}}
5454
packer build -var "git-head-version=${GIT_SHA}" -var "packer-execution-id=${GITHUB_RUN_ID}" -var-file="development-arm.vars.pkr.hcl" -var-file="common-nix.vars.pkr.hcl" -var "postgres-version=${{ steps.random.outputs.random_string }}" -var "region=ap-southeast-1" -var 'ami_regions=["ap-southeast-1"]' -var "force-deregister=true" -var "git_sha=${GITHUB_SHA}" stage2-nix-psql.pkr.hcl
5555
56-
- name: Launch temporary instance
57-
id: launch-instance
58-
run: |
59-
AMI_NAME="supabase-postgres-${{ steps.random.outputs.random_string }}-pre-resize"
60-
INSTANCE_ID=$(aws ec2 run-instances --image-id $(aws ec2 describe-images --owners self --filters "Name=name,Values=${AMI_NAME}" --query 'Images[0].ImageId' --output text) --instance-type t4g.micro --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=AMI-Resize-Temp}]' --query 'Instances[0].InstanceId' --output text)
61-
echo "INSTANCE_ID=${INSTANCE_ID}" >> $GITHUB_OUTPUT
62-
63-
- name: Wait for instance to be running
64-
run: aws ec2 wait instance-running --instance-ids ${{ steps.launch-instance.outputs.INSTANCE_ID }}
65-
66-
- name: Resize filesystem
67-
run: |
68-
aws ec2 start-session --target ${{ steps.launch-instance.outputs.INSTANCE_ID }} --document-name AWS-StartInteractiveCommand --parameters '{"command":["sudo e2fsck -f /dev/sda1 && sudo resize2fs /dev/sda1 8G && sudo sync"]}'
69-
70-
- name: Create new AMI
71-
id: create-ami
72-
run: |
73-
NEW_AMI_NAME="supabase-postgres-${{ steps.random.outputs.random_string }}"
74-
NEW_AMI_ID=$(aws ec2 create-image --instance-id ${{ steps.launch-instance.outputs.INSTANCE_ID }} --name "${NEW_AMI_NAME}" --description "Resized AMI" --query 'ImageId' --output text)
75-
echo "NEW_AMI_ID=${NEW_AMI_ID}" >> $GITHUB_OUTPUT
76-
echo "NEW_AMI_NAME=${NEW_AMI_NAME}" >> $GITHUB_OUTPUT
77-
78-
- name: Wait for AMI to be available
79-
run: aws ec2 wait image-available --image-ids ${{ steps.create-ami.outputs.NEW_AMI_ID }}
56+
- name: Set up Python
57+
uses: actions/setup-python@v4
58+
with:
59+
python-version: '3.x'
8060

81-
- name: Modify AMI block device mapping
61+
- name: Run AMI resize script
62+
env:
63+
PRE_AMI_NAME: "supabase-postgres-${{ steps.random.outputs.random_string }}-pre-resize"
64+
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
65+
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
66+
AWS_DEFAULT_REGION: ap-southeast-1
8267
run: |
83-
aws ec2 modify-image-attribute --image-id ${{ steps.create-ami.outputs.NEW_AMI_ID }} --block-device-mappings '[{"DeviceName": "/dev/sda1","Ebs":{"VolumeSize":8}}]'
84-
85-
- name: Terminate temporary instance
86-
run: aws ec2 terminate-instances --instance-ids ${{ steps.launch-instance.outputs.INSTANCE_ID }}
68+
pip install boto3 boto3-stubs[essential] ec2instanceconnectcli
69+
python scripts/ami_resize_script.py
8770
8871
- name: Run tests
8972
timeout-minutes: 10

scripts/aws_resize.py

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import os
2+
import boto3
3+
import time
4+
from ec2instanceconnectcli.ec2instanceconnectcli import EC2InstanceConnectCLI
5+
6+
# Initialize boto3 clients
7+
ec2_client = boto3.client('ec2')
8+
ec2_resource = boto3.resource('ec2')
9+
10+
# Get the AMI name from environment variable
11+
AMI_NAME = os.environ.get('PRE_AMI_NAME')
12+
13+
def launch_temporary_instance():
14+
# Describe the AMI
15+
images = ec2_client.describe_images(Owners=['self'], Filters=[{'Name': 'name', 'Values': [AMI_NAME]}])
16+
if not images['Images']:
17+
raise Exception(f"No AMI found with name: {AMI_NAME}")
18+
image_id = images['Images'][0]['ImageId']
19+
20+
# Launch the instance
21+
instance = ec2_resource.create_instances(
22+
ImageId=image_id,
23+
InstanceType='t4g.micro',
24+
MinCount=1,
25+
MaxCount=1,
26+
TagSpecifications=[
27+
{
28+
'ResourceType': 'instance',
29+
'Tags': [{'Key': 'Name', 'Value': 'AMI-Resize-Temp'}]
30+
}
31+
]
32+
)[0]
33+
34+
print(f"Launched instance: {instance.id}")
35+
return instance.id
36+
37+
def wait_for_instance_running(instance_id):
38+
instance = ec2_resource.Instance(instance_id)
39+
instance.wait_until_running()
40+
print(f"Instance {instance_id} is now running")
41+
42+
def resize_filesystem(instance_id):
43+
cli = EC2InstanceConnectCLI()
44+
command = "sudo e2fsck -f /dev/sda1 && sudo resize2fs /dev/sda1 8G && sudo sync"
45+
cli.start_session(instance_id=instance_id, command=command)
46+
47+
def create_new_ami(instance_id):
48+
new_ami_name = f"supabase-postgres-{os.environ.get('GITHUB_RUN_ID', 'resized')}"
49+
response = ec2_client.create_image(
50+
InstanceId=instance_id,
51+
Name=new_ami_name,
52+
Description="Resized AMI"
53+
)
54+
new_ami_id = response['ImageId']
55+
print(f"Created new AMI: {new_ami_id} with name: {new_ami_name}")
56+
return new_ami_id, new_ami_name
57+
58+
def wait_for_ami_available(ami_id):
59+
waiter = ec2_client.get_waiter('image_available')
60+
waiter.wait(ImageIds=[ami_id])
61+
print(f"AMI {ami_id} is now available")
62+
63+
def modify_ami_block_device_mapping(ami_id):
64+
ec2_client.modify_image_attribute(
65+
ImageId=ami_id,
66+
BlockDeviceMappings=[
67+
{
68+
'DeviceName': '/dev/sda1',
69+
'Ebs': {'VolumeSize': 8}
70+
}
71+
]
72+
)
73+
print(f"Modified block device mapping for AMI {ami_id}")
74+
75+
def terminate_instance(instance_id):
76+
ec2_resource.Instance(instance_id).terminate()
77+
print(f"Terminated instance {instance_id}")
78+
79+
def main():
80+
try:
81+
instance_id = launch_temporary_instance()
82+
wait_for_instance_running(instance_id)
83+
resize_filesystem(instance_id)
84+
new_ami_id, new_ami_name = create_new_ami(instance_id)
85+
wait_for_ami_available(new_ami_id)
86+
modify_ami_block_device_mapping(new_ami_id)
87+
finally:
88+
if 'instance_id' in locals():
89+
terminate_instance(instance_id)
90+
91+
print(f"NEW_AMI_ID={new_ami_id}")
92+
print(f"NEW_AMI_NAME={new_ami_name}")
93+
94+
if __name__ == "__main__":
95+
main()

0 commit comments

Comments
 (0)