343 lines
11 KiB
Python
343 lines
11 KiB
Python
import boto3
|
|
from boto3.s3.transfer import S3Transfer
|
|
from boto3.s3.transfer import TransferConfig
|
|
import base64
|
|
import os
|
|
|
|
REPOZYTORIUM = "https://git.wmi.amu.edu.pl/s464863/aws_faktury.git"
|
|
PREFIX = "s464863"
|
|
AMI_ID = "ami-0b5eea76982371e91"
|
|
REGION = "us-east-1"
|
|
INSTANCE_TYPE = "t2.micro"
|
|
|
|
user_data = f"""
|
|
#!/bin/bash
|
|
|
|
yum update -y
|
|
yum install -y amazon-linux-extras
|
|
amazon-linux-extras enable docker
|
|
yum install -y docker
|
|
yum install -y git
|
|
|
|
service docker start
|
|
usermod -a -G docker ec2-user
|
|
|
|
cd /home/ec2-user
|
|
git clone {REPOZYTORIUM}
|
|
cd aws_faktury
|
|
|
|
docker build -t flask-invoice-app .
|
|
|
|
docker run -d -p 8080:8080 -p 80:80 flask-invoice-app
|
|
echo "Aplikacja działa na porcie 8080"
|
|
"""
|
|
|
|
def create_vpc(ec2_client):
|
|
# 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):
|
|
# 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}")
|
|
|
|
# Public IP addresses for instances in the subnet
|
|
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):
|
|
# 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}")
|
|
|
|
# Attach Internet Gateway to VPC
|
|
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):
|
|
# 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}")
|
|
|
|
# Create route to Internet Gateway
|
|
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.")
|
|
|
|
# Associate Route Table with Subnet
|
|
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)
|
|
|
|
# Save private key to file
|
|
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):
|
|
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}")
|
|
|
|
# Set ingress rules
|
|
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):
|
|
# 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):
|
|
# Run EC2 instances
|
|
response = ec2_client.run_instances(
|
|
LaunchTemplate={
|
|
'LaunchTemplateId': launch_template_id
|
|
},
|
|
MaxCount=1,
|
|
MinCount=1,
|
|
SubnetId=subnet_id
|
|
)
|
|
|
|
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}")
|
|
create_js_scripts(public_ip)
|
|
if public_dns:
|
|
print(f"Public DNS: {public_dns}")
|
|
|
|
return instance_id
|
|
|
|
def create_js_scripts(ip):
|
|
js_content = r"""
|
|
document.getElementById('uploadForm').addEventListener('submit', function (event) {
|
|
event.preventDefault();
|
|
|
|
const fileInput = document.getElementById('file');
|
|
const file = fileInput.files[0];
|
|
|
|
if (file) {
|
|
const formData = new FormData();
|
|
formData.append('file', file);
|
|
fetch('http://""" + ip + """:8080/invoice', {
|
|
method: 'POST',
|
|
body: formData,
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
document.getElementById('responseMessage').innerHTML = `
|
|
<p>Upload successful!</p>
|
|
<pre>${JSON.stringify(data, null, 2)}</pre>
|
|
`;
|
|
})
|
|
.catch(error => {
|
|
document.getElementById('responseMessage').innerHTML = `
|
|
<p>Error during file upload: ${error.message}</p>
|
|
`;
|
|
});
|
|
} else {
|
|
alert('Please select file!');
|
|
}
|
|
});
|
|
"""
|
|
|
|
with open('static/scripts.js', 'w') as js_file:
|
|
js_file.write(js_content)
|
|
print(f"Generated scripts.js with ip: {ip}")
|
|
|
|
def create_s3_bucket(s3_client, bucket_name):
|
|
s3_client.create_bucket(
|
|
Bucket=bucket_name,
|
|
)
|
|
print(f"S3 bucket '{bucket_name}' created.")
|
|
|
|
s3_client.put_bucket_website(
|
|
Bucket=bucket_name,
|
|
WebsiteConfiguration={
|
|
'IndexDocument': {'Suffix': 'index.html'},
|
|
}
|
|
)
|
|
print(f"Static website hosting configured for '{bucket_name}'.")
|
|
|
|
return bucket_name
|
|
|
|
def upload_files_to_s3(s3_client, bucket_name, folder_path):
|
|
config = TransferConfig(multipart_chunksize=50 * 1024 * 1024)
|
|
transfer = S3Transfer(s3_client, config)
|
|
for root, dirs, files in os.walk(folder_path):
|
|
for file in files:
|
|
file_path = os.path.join(root, file)
|
|
try:
|
|
s3_key = os.path.relpath(file_path, folder_path)
|
|
transfer.upload_file(file_path, bucket_name, s3_key)
|
|
print(f"Uploaded {file} to S3 bucket '{bucket_name}' at key '{s3_key}'.")
|
|
except Exception as e:
|
|
print(f"Failed to upload {file} to S3 bucket '{bucket_name}': {str(e)}")
|
|
|
|
def main():
|
|
# Create EC2 client
|
|
ec2_client = boto3.client('ec2', region_name=REGION)
|
|
|
|
# Create S3 client
|
|
s3_client = boto3.client('s3', region_name=REGION)
|
|
|
|
# Create VPC
|
|
print("Creating VPC...")
|
|
vpc_id = create_vpc(ec2_client)
|
|
|
|
# Create subnet
|
|
print("Creating subnet...")
|
|
subnet = create_subnet(ec2_client, vpc_id, cidr_block='10.0.1.0/24', availability_zone='us-east-1a')
|
|
|
|
# Create Internet Gateway
|
|
print("Creating Internet Gateway...")
|
|
igw_id = create_internet_gateway(ec2_client, vpc_id)
|
|
|
|
# Create Route Table
|
|
print("Creating Route Table...")
|
|
route_table_id = create_route_table(ec2_client, vpc_id, subnet, igw_id)
|
|
|
|
# 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)
|
|
|
|
# Create Launch Template
|
|
print("Creating Launch Template...")
|
|
launch_template_id = create_launch_template(ec2_client, key_name, security_group_id)
|
|
|
|
# Run EC2 instance
|
|
print("Running EC2 instance...")
|
|
ec2_id = run_instance(ec2_client, launch_template_id, subnet)
|
|
|
|
# Create S3 bucket
|
|
print("Creating S3 bucket...")
|
|
bucket_name = create_s3_bucket(s3_client, f"{PREFIX}-bucket")
|
|
bucket_name = "s464863-bucket"
|
|
|
|
# Upload files to S3
|
|
print("Uploading files to S3...")
|
|
upload_files_to_s3(s3_client, bucket_name, 'static')
|
|
|
|
if __name__ == '__main__':
|
|
main() |