import os from aws_cdk import ( Stack, aws_ec2 as ec2, aws_iam as iam, CfnOutput ) from constructs import Construct class IptvUpdaterStack(Stack): def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: super().__init__(scope, construct_id, **kwargs) # Create VPC vpc = ec2.Vpc(self, "IptvUpdaterVPC", max_azs=1, # Use only one AZ for free tier nat_gateways=0, # No NAT Gateway to stay in free tier subnet_configuration=[ ec2.SubnetConfiguration( name="public", subnet_type=ec2.SubnetType.PUBLIC, cidr_mask=24 ) ] ) # Security Group security_group = ec2.SecurityGroup( self, "IptvUpdaterSG", vpc=vpc, allow_all_outbound=True ) security_group.add_ingress_rule( ec2.Peer.any_ipv4(), ec2.Port.tcp(443), "Allow HTTPS traffic" ) security_group.add_ingress_rule( ec2.Peer.any_ipv4(), ec2.Port.tcp(80), "Allow HTTP traffic" ) security_group.add_ingress_rule( ec2.Peer.any_ipv4(), ec2.Port.tcp(22), "Allow SSH traffic" ) # Key pair for IPTV Updater instance key_pair = ec2.KeyPair(self, "IptvUpdaterKeyPair", key_pair_name="iptv-updater-key" ) # Create IAM role for EC2 role = iam.Role( self, "IptvUpdaterRole", assumed_by=iam.ServicePrincipal("ec2.amazonaws.com") ) # Add SSM managed policy role.add_managed_policy( iam.ManagedPolicy.from_aws_managed_policy_name( "AmazonSSMManagedInstanceCore" ) ) # Read the userdata script with proper path resolution script_dir = os.path.dirname(os.path.abspath(__file__)) userdata_path = os.path.join(script_dir, "userdata.sh") userdata_file = open(userdata_path, "rb").read() # Creates a userdata object for Linux hosts userdata = ec2.UserData.for_linux() # Adds one or more commands to the userdata object. userdata.add_commands(str(userdata_file, 'utf-8')) # EC2 Instance instance = ec2.Instance( self, "IptvUpdaterInstance", vpc=vpc, instance_type=ec2.InstanceType.of( ec2.InstanceClass.T2, ec2.InstanceSize.MICRO ), machine_image=ec2.AmazonLinuxImage( generation=ec2.AmazonLinuxGeneration.AMAZON_LINUX_2 ), security_group=security_group, key_pair=key_pair, role=role, user_data=userdata, ) # Output the public DNS name CfnOutput( self, "InstancePublicDNS", value=instance.instance_public_dns_name )