Upload files to "/"
This commit is contained in:
commit
f61da53096
308
aws.py
Normal file
308
aws.py
Normal file
@ -0,0 +1,308 @@
|
||||
import boto3
|
||||
import base64
|
||||
import os
|
||||
from dotenv import load_dotenv
|
||||
import uuid
|
||||
|
||||
def create_vpc(ec2_client, prefix):
|
||||
# Create VPC
|
||||
response = ec2_client.create_vpc(
|
||||
CidrBlock='10.0.0.0/16',
|
||||
TagSpecifications=[
|
||||
{
|
||||
'ResourceType': 'vpc',
|
||||
'Tags': [{'Key': 'Name', 'Value': f"{prefix}-vpc"}]
|
||||
}
|
||||
]
|
||||
)
|
||||
vpc_id = response['Vpc']['VpcId']
|
||||
print(f"Created VPC with ID: {vpc_id}")
|
||||
|
||||
# Enable DNS support and hostnames
|
||||
ec2_client.modify_vpc_attribute(VpcId=vpc_id, EnableDnsSupport={'Value': True})
|
||||
ec2_client.modify_vpc_attribute(VpcId=vpc_id, EnableDnsHostnames={'Value': True})
|
||||
print("Enabled DNS support and hostnames.")
|
||||
|
||||
return vpc_id
|
||||
|
||||
|
||||
def create_subnet(ec2_client, vpc_id, cidr_block, availability_zone, prefix):
|
||||
# Create subnet
|
||||
response = ec2_client.create_subnet(
|
||||
VpcId=vpc_id,
|
||||
CidrBlock=cidr_block,
|
||||
AvailabilityZone=availability_zone,
|
||||
TagSpecifications=[
|
||||
{
|
||||
'ResourceType': 'subnet',
|
||||
'Tags': [{'Key': 'Name', 'Value': f"{prefix}-subnet"}]
|
||||
}
|
||||
]
|
||||
)
|
||||
subnet_id = response['Subnet']['SubnetId']
|
||||
print(f"Created Subnet with ID: {subnet_id}")
|
||||
|
||||
ec2_client.modify_subnet_attribute(SubnetId=subnet_id, MapPublicIpOnLaunch={'Value': True})
|
||||
print("Configured subnet to auto-assign public IP addresses.")
|
||||
|
||||
return subnet_id
|
||||
|
||||
|
||||
def create_internet_gateway(ec2_client, vpc_id, prefix):
|
||||
# Create Internet Gateway
|
||||
response = ec2_client.create_internet_gateway(
|
||||
TagSpecifications=[
|
||||
{
|
||||
'ResourceType': 'internet-gateway',
|
||||
'Tags': [{'Key': 'Name', 'Value': f"{prefix}-igw"}]
|
||||
}
|
||||
]
|
||||
)
|
||||
igw_id = response['InternetGateway']['InternetGatewayId']
|
||||
print(f"Created Internet Gateway with ID: {igw_id}")
|
||||
|
||||
ec2_client.attach_internet_gateway(InternetGatewayId=igw_id, VpcId=vpc_id)
|
||||
print("Attached Internet Gateway to VPC.")
|
||||
|
||||
return igw_id
|
||||
|
||||
|
||||
def create_route_table(ec2_client, vpc_id, subnet_id, igw_id, prefix):
|
||||
# Create Route Table
|
||||
response = ec2_client.create_route_table(
|
||||
VpcId=vpc_id,
|
||||
TagSpecifications=[
|
||||
{
|
||||
'ResourceType': 'route-table',
|
||||
'Tags': [{'Key': 'Name', 'Value': f"{prefix}-rt"}]
|
||||
}
|
||||
]
|
||||
)
|
||||
route_table_id = response['RouteTable']['RouteTableId']
|
||||
print(f"Created Route Table with ID: {route_table_id}")
|
||||
|
||||
ec2_client.create_route(
|
||||
RouteTableId=route_table_id,
|
||||
DestinationCidrBlock='0.0.0.0/0',
|
||||
GatewayId=igw_id
|
||||
)
|
||||
print("Added route to Internet Gateway in Route Table.")
|
||||
|
||||
ec2_client.associate_route_table(RouteTableId=route_table_id, SubnetId=subnet_id)
|
||||
print("Associated Route Table with Subnet.")
|
||||
|
||||
return route_table_id
|
||||
|
||||
|
||||
def create_key_pair(ec2_client, key_name, save_to_file):
|
||||
# Create key pair
|
||||
response = ec2_client.create_key_pair(KeyName=key_name)
|
||||
|
||||
private_key = response['KeyMaterial']
|
||||
with open(save_to_file, 'w') as file:
|
||||
file.write(private_key)
|
||||
|
||||
print(f"Key pair '{key_name}' created and saved to '{save_to_file}'.")
|
||||
return response['KeyName']
|
||||
|
||||
|
||||
def create_security_group(ec2_client, vpc_id, prefix):
|
||||
group_name = f"{prefix}-sg"
|
||||
|
||||
# Create Security Group
|
||||
response = ec2_client.create_security_group(
|
||||
GroupName=group_name,
|
||||
Description=f"Security group for {prefix} webservices",
|
||||
VpcId=vpc_id
|
||||
)
|
||||
|
||||
security_group_id = response['GroupId']
|
||||
print(f"Security group '{group_name}' created with ID: {security_group_id}")
|
||||
|
||||
ec2_client.authorize_security_group_ingress(
|
||||
GroupId=security_group_id,
|
||||
IpPermissions=[
|
||||
{
|
||||
'IpProtocol': 'tcp',
|
||||
'FromPort': 22,
|
||||
'ToPort': 22,
|
||||
'IpRanges': [{'CidrIp': '0.0.0.0/0', 'Description': 'SSH access'}]
|
||||
},
|
||||
{
|
||||
'IpProtocol': 'tcp',
|
||||
'FromPort': 8080,
|
||||
'ToPort': 8080,
|
||||
'IpRanges': [{'CidrIp': '0.0.0.0/0', 'Description': 'HTTP access'}]
|
||||
},
|
||||
{
|
||||
'IpProtocol': 'tcp',
|
||||
'FromPort': 80,
|
||||
'ToPort': 80,
|
||||
'IpRanges': [{'CidrIp': '0.0.0.0/0', 'Description': 'HTTP access'}]
|
||||
}
|
||||
]
|
||||
)
|
||||
|
||||
print("Ingress rules added for SSH (22) and HTTP (80).")
|
||||
return security_group_id
|
||||
|
||||
|
||||
def create_launch_template(ec2_client, key_name, security_group_id, instance_type, image_id, prefix, ami_id):
|
||||
user_data = f"""
|
||||
#!/bin/bash
|
||||
|
||||
yum update -y
|
||||
yum install -y amazon-linux-extras
|
||||
amazon-linux-extras enable docker
|
||||
yum install -y docker
|
||||
|
||||
service docker start
|
||||
usermod -a -G docker ec2-user
|
||||
|
||||
docker run -d --rm -p 8080:3000 {image_id}
|
||||
echo "Aplikacja działa na porcie 8080"
|
||||
"""
|
||||
|
||||
# Create Launch Template
|
||||
response = ec2_client.create_launch_template(
|
||||
LaunchTemplateName=f"{prefix}-lt",
|
||||
LaunchTemplateData={
|
||||
'ImageId': ami_id,
|
||||
'InstanceType': instance_type,
|
||||
'SecurityGroupIds': [security_group_id],
|
||||
'KeyName': key_name,
|
||||
'UserData': base64.b64encode(user_data.encode('utf-8')).decode('utf-8')
|
||||
}
|
||||
)
|
||||
|
||||
print(f"Launch Template created with ID: {response['LaunchTemplate']['LaunchTemplateId']}")
|
||||
return response['LaunchTemplate']['LaunchTemplateId']
|
||||
|
||||
|
||||
def run_instance(ec2_client, launch_template_id, subnet_id, docker_image_name):
|
||||
name = f"{docker_image_name}-{uuid.uuid4()}"
|
||||
|
||||
# Run EC2 instances
|
||||
response = ec2_client.run_instances(
|
||||
LaunchTemplate={
|
||||
'LaunchTemplateId': launch_template_id
|
||||
},
|
||||
MaxCount=1,
|
||||
MinCount=1,
|
||||
SubnetId=subnet_id,
|
||||
TagSpecifications=[
|
||||
{
|
||||
'ResourceType': 'instance',
|
||||
'Tags': [
|
||||
{'Key': 'Name', 'Value': name}
|
||||
]
|
||||
}
|
||||
]
|
||||
)
|
||||
|
||||
instance_id = response['Instances'][0]['InstanceId']
|
||||
print(f"Instance {instance_id} is running.")
|
||||
|
||||
ec2_client.get_waiter('instance_running').wait(InstanceIds=[instance_id])
|
||||
instance_info = ec2_client.describe_instances(InstanceIds=[instance_id])
|
||||
public_ip = instance_info['Reservations'][0]['Instances'][0].get('PublicIpAddress')
|
||||
public_dns = instance_info['Reservations'][0]['Instances'][0].get('PublicDnsName')
|
||||
|
||||
if public_ip:
|
||||
print(f"Public IP: {public_ip}")
|
||||
if public_dns:
|
||||
print(f"Public DNS: {public_dns}")
|
||||
|
||||
return {
|
||||
"instance_id": instance_id,
|
||||
"name": name,
|
||||
"public_ip": public_ip,
|
||||
"public_dns": public_dns
|
||||
}
|
||||
|
||||
def get_matching_instance_type(ec2_client, cpu, ram, ami_id):
|
||||
# Get the architecture of the specified AMI
|
||||
ami_response = ec2_client.describe_images(ImageIds=[ami_id])
|
||||
ami_architecture = ami_response['Images'][0]['Architecture']
|
||||
|
||||
best_match = None
|
||||
best_match_vcpu = float('inf')
|
||||
best_match_ram = float('inf')
|
||||
|
||||
# Describe all available instance types
|
||||
paginator = ec2_client.get_paginator('describe_instance_types')
|
||||
for page in paginator.paginate():
|
||||
for instance_type in page['InstanceTypes']:
|
||||
instance_architectures = instance_type['ProcessorInfo']['SupportedArchitectures']
|
||||
instance_vcpu = instance_type['VCpuInfo']['DefaultVCpus']
|
||||
instance_ram = instance_type['MemoryInfo']['SizeInMiB'] / 1024 # Convert MiB to GiB
|
||||
|
||||
# Check if the instance meets or exceeds the requirements and matches the AMI architecture
|
||||
if (ami_architecture in instance_architectures and
|
||||
instance_vcpu >= cpu and instance_ram >= ram):
|
||||
# Update best match if it's closer to the requirements
|
||||
if (instance_vcpu < best_match_vcpu or
|
||||
(instance_vcpu == best_match_vcpu and instance_ram < best_match_ram)):
|
||||
best_match = instance_type['InstanceType']
|
||||
best_match_vcpu = instance_vcpu
|
||||
best_match_ram = instance_ram
|
||||
|
||||
print(best_match)
|
||||
return best_match
|
||||
|
||||
def run_container(docker_image_name, ram, cpu):
|
||||
load_dotenv()
|
||||
|
||||
aws_access_key = os.getenv("AWS_ACCESS_KEY_ID")
|
||||
aws_secret_key = os.getenv("AWS_SECRET_ACCESS_KEY")
|
||||
aws_session_token = os.getenv("AWS_SESSION_TOKEN")
|
||||
aws_region = os.getenv("AWS_REGION", "us-east-1")
|
||||
|
||||
prefix = "454353"
|
||||
ami_id = "ami-0b5eea76982371e91"
|
||||
|
||||
ec2_client = boto3.client('ec2', region_name=aws_region, aws_access_key_id=aws_access_key,
|
||||
aws_secret_access_key=aws_secret_key,
|
||||
aws_session_token=aws_session_token)
|
||||
|
||||
instance_type = get_matching_instance_type(ec2_client, cpu, ram, ami_id)
|
||||
|
||||
# Create VPC
|
||||
print("Creating VPC...")
|
||||
vpc_id = create_vpc(ec2_client, prefix)
|
||||
|
||||
# Create subnet
|
||||
print("Creating subnet...")
|
||||
subnet = create_subnet(ec2_client, vpc_id, cidr_block='10.0.1.0/24', availability_zone='us-east-1a', prefix=prefix)
|
||||
|
||||
# Create Internet Gateway
|
||||
print("Creating Internet Gateway...")
|
||||
igw_id = create_internet_gateway(ec2_client, vpc_id, prefix)
|
||||
|
||||
# Create Route Table
|
||||
print("Creating Route Table...")
|
||||
route_table_id = create_route_table(ec2_client, vpc_id, subnet, igw_id, prefix)
|
||||
|
||||
# Create Key Pair
|
||||
print("Creating Key Pair...")
|
||||
key_name = create_key_pair(ec2_client, f"{prefix}-key", f"{prefix}-key.pem")
|
||||
|
||||
# Create Security Group
|
||||
print("Creating Security Group...")
|
||||
security_group_id = create_security_group(ec2_client, vpc_id, prefix)
|
||||
|
||||
# Create Launch Template
|
||||
print("Creating Launch Template...")
|
||||
launch_template_id = create_launch_template(ec2_client, key_name, security_group_id, instance_type, docker_image_name, prefix, ami_id)
|
||||
|
||||
# Run EC2 instance
|
||||
print("Running EC2 instance...")
|
||||
|
||||
return run_instance(ec2_client, launch_template_id, subnet, docker_image_name)
|
||||
|
||||
def main():
|
||||
run_container("nmatsui/hello-world-api", 2, 1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
5
requirements.txt
Normal file
5
requirements.txt
Normal file
@ -0,0 +1,5 @@
|
||||
azure-mgmt-containerinstance
|
||||
azure-identity
|
||||
python-dotenv
|
||||
boto3
|
||||
hetzner
|
Loading…
Reference in New Issue
Block a user