def __init__(self, scope: core.Construct, id: str, env, instance_id) -> None: super().__init__(scope, id, env=env) self.instance_id = instance_id # pelican.com ACM cert self.sel_cert_arn = "arn:aws:acm:us-east-2:111111111111:certificate/b8299bf5-ae3b-4f69-a696-f1d839428f5f" self.vpc = ec2.Vpc.from_vpc_attributes( self, "VPC", vpc_id='vpc-44a44b44', availability_zones=['us-east-2a', 'us-east-2c'], public_subnet_ids=['subnet-bbbbbbbb', 'subnet-cccccccc']) self.target = elbv2.InstanceTarget(instance_id=instance_id) self.lb = elbv2.CfnLoadBalancer( scope=self, id='LB', ip_address_type='ipv4', name='pelican-alb', security_groups=['sg-13a02c7a', 'sg-12a02c7b', 'sg-3bb23e52', 'sg-14a02c7d'], type='application', scheme='internet-facing', subnets=['subnet-bbbbbbbb', 'subnet-cccccccc'], tags=[core.CfnTag(key='env', value='dev')], load_balancer_attributes=[elbv2.CfnLoadBalancer.LoadBalancerAttributeProperty( key='idle_timeout.timeout_seconds', value='180' )] ) core.Tag.add(self.lb, key='cfn.single-env.stack', value='alb-stack') self.alb_dns = self.lb.attr_dns_name self.listener_443 = None
def __init__(self, scope: core.Construct, id: str, vpc: ec2.IVpc, instances: list, certificate_arn: str, **kwargs): super().__init__(scope, id, **kwargs) health_check = elbv2.HealthCheck(path="/", healthy_http_codes="200-399") public_target_group = elbv2.ApplicationTargetGroup( self, "PublicTG", port=8080, vpc=vpc, health_check=health_check) for instance in instances: public_target_group.add_target( elbv2.InstanceTarget(instance.instance_id, port=8080)) self._public_security_group = ec2.SecurityGroup(self, "PublicLBSG", vpc=vpc) self._public_security_group.add_ingress_rule(ec2.Peer.any_ipv4(), ec2.Port.tcp(443)) self._public_lb = elbv2.ApplicationLoadBalancer( self, "PublicLB", vpc=vpc, vpc_subnets=ec2.SubnetSelection(subnets=vpc.select_subnets( subnet_type=ec2.SubnetType.PUBLIC).subnets), internet_facing=True, security_group=self._public_security_group) self._public_lb.add_listener( "PublicLBListener", certificates=[elbv2.ListenerCertificate(certificate_arn)], port=443, default_target_groups=[public_target_group]) core.CfnOutput(self, "CloudIDE URL", value="https://{}".format( self._public_lb.load_balancer_dns_name))
def __init__(self, scope: core.Construct, id: str, vpc: ec2.IVpc, instances: list, **kwargs): super().__init__(scope, id, **kwargs) health_check = elbv2.HealthCheck(path="/login") public_target_group = elbv2.ApplicationTargetGroup( self, "PublicTG", port=8080, vpc=vpc, health_check=health_check) for instance in instances: public_target_group.add_target( elbv2.InstanceTarget(instance.instance_id, port=8080)) private_target_group = elbv2.ApplicationTargetGroup( self, "PrivateTG", port=8080, vpc=vpc, health_check=health_check) for instance in instances: private_target_group.add_target( elbv2.InstanceTarget(instance.instance_id, port=8080)) self._public_security_group = ec2.SecurityGroup(self, "PublicLBSG", vpc=vpc) self._public_security_group.add_ingress_rule( ec2.Peer.any_ipv4(), ec2.Port.tcp(80), ) self._public_lb = elbv2.ApplicationLoadBalancer( self, "PublicLB", vpc=vpc, vpc_subnets=ec2.SubnetSelection(subnets=vpc.select_subnets( subnet_type=ec2.SubnetType.PUBLIC).subnets), internet_facing=True, security_group=self._public_security_group) self._public_lb.add_listener( "PublicLBListener", port=80, default_target_groups=[public_target_group]) self._private_security_group = ec2.SecurityGroup(self, "PrivateLBSG", vpc=vpc) self._private_security_group.add_ingress_rule( ec2.Peer.any_ipv4(), ec2.Port.tcp(80), ) self._private_lb = elbv2.ApplicationLoadBalancer( self, "PrivateLB", vpc=vpc, vpc_subnets=ec2.SubnetSelection(subnets=vpc.select_subnets( subnet_type=ec2.SubnetType.PRIVATE).subnets), internet_facing=False, security_group=self._private_security_group) self._private_lb.add_listener( "PrivateLBListener", port=80, default_target_groups=[private_target_group])
def __init__(self, scope: core.Construct, id: str, **kwargs) -> None: super().__init__(scope, id, **kwargs) eks_vpc = ec2.Vpc(self, "VPC", cidr="10.0.0.0/16") self.eks_vpc = eks_vpc # Create IAM Role For code-server bastion bastion_role = iam.Role( self, "BastionRole", assumed_by=iam.CompositePrincipal( iam.ServicePrincipal("ec2.amazonaws.com"), iam.AccountRootPrincipal()), managed_policies=[ iam.ManagedPolicy.from_aws_managed_policy_name( "AdministratorAccess") ]) self.bastion_role = bastion_role # Create EC2 Instance Profile for that Role instance_profile = iam.CfnInstanceProfile( self, "InstanceProfile", roles=[bastion_role.role_name]) # Create SecurityGroup for the Control Plane ENIs eks_security_group = ec2.SecurityGroup(self, "EKSSecurityGroup", vpc=eks_vpc, allow_all_outbound=True) eks_security_group.add_ingress_rule(ec2.Peer.ipv4('10.0.0.0/16'), ec2.Port.all_traffic()) # Create an EKS Cluster eks_cluster = eks.Cluster( self, "cluster", cluster_name="cluster", vpc=eks_vpc, masters_role=bastion_role, default_capacity_type=eks.DefaultCapacityType.NODEGROUP, default_capacity_instance=ec2.InstanceType("m5.large"), default_capacity=2, security_group=eks_security_group, endpoint_access=eks.EndpointAccess.PUBLIC_AND_PRIVATE, version=eks.KubernetesVersion.V1_17) self.cluster_cert = eks_cluster.cluster_certificate_authority_data # Deploy ALB Ingress Controller # Create the k8s Service account and corresponding IAM Role mapped via IRSA alb_service_account = eks_cluster.add_service_account( "alb-ingress-controller", name="alb-ingress-controller", namespace="kube-system") # Create the PolicyStatements to attach to the role # I couldn't find a way to get this to work with a PolicyDocument and there are 10 of these alb_policy_statement_json_1 = { "Effect": "Allow", "Action": [ "acm:DescribeCertificate", "acm:ListCertificates", "acm:GetCertificate" ], "Resource": "*" } alb_policy_statement_json_2 = { "Effect": "Allow", "Action": [ "ec2:AuthorizeSecurityGroupIngress", "ec2:CreateSecurityGroup", "ec2:CreateTags", "ec2:DeleteTags", "ec2:DeleteSecurityGroup", "ec2:DescribeAccountAttributes", "ec2:DescribeAddresses", "ec2:DescribeInstances", "ec2:DescribeInstanceStatus", "ec2:DescribeInternetGateways", "ec2:DescribeNetworkInterfaces", "ec2:DescribeSecurityGroups", "ec2:DescribeSubnets", "ec2:DescribeTags", "ec2:DescribeVpcs", "ec2:ModifyInstanceAttribute", "ec2:ModifyNetworkInterfaceAttribute", "ec2:RevokeSecurityGroupIngress" ], "Resource": "*" } alb_policy_statement_json_3 = { "Effect": "Allow", "Action": [ "elasticloadbalancing:AddListenerCertificates", "elasticloadbalancing:AddTags", "elasticloadbalancing:CreateListener", "elasticloadbalancing:CreateLoadBalancer", "elasticloadbalancing:CreateRule", "elasticloadbalancing:CreateTargetGroup", "elasticloadbalancing:DeleteListener", "elasticloadbalancing:DeleteLoadBalancer", "elasticloadbalancing:DeleteRule", "elasticloadbalancing:DeleteTargetGroup", "elasticloadbalancing:DeregisterTargets", "elasticloadbalancing:DescribeListenerCertificates", "elasticloadbalancing:DescribeListeners", "elasticloadbalancing:DescribeLoadBalancers", "elasticloadbalancing:DescribeLoadBalancerAttributes", "elasticloadbalancing:DescribeRules", "elasticloadbalancing:DescribeSSLPolicies", "elasticloadbalancing:DescribeTags", "elasticloadbalancing:DescribeTargetGroups", "elasticloadbalancing:DescribeTargetGroupAttributes", "elasticloadbalancing:DescribeTargetHealth", "elasticloadbalancing:ModifyListener", "elasticloadbalancing:ModifyLoadBalancerAttributes", "elasticloadbalancing:ModifyRule", "elasticloadbalancing:ModifyTargetGroup", "elasticloadbalancing:ModifyTargetGroupAttributes", "elasticloadbalancing:RegisterTargets", "elasticloadbalancing:RemoveListenerCertificates", "elasticloadbalancing:RemoveTags", "elasticloadbalancing:SetIpAddressType", "elasticloadbalancing:SetSecurityGroups", "elasticloadbalancing:SetSubnets", "elasticloadbalancing:SetWebAcl" ], "Resource": "*" } alb_policy_statement_json_4 = { "Effect": "Allow", "Action": [ "iam:CreateServiceLinkedRole", "iam:GetServerCertificate", "iam:ListServerCertificates" ], "Resource": "*" } alb_policy_statement_json_5 = { "Effect": "Allow", "Action": ["cognito-idp:DescribeUserPoolClient"], "Resource": "*" } alb_policy_statement_json_6 = { "Effect": "Allow", "Action": [ "waf-regional:GetWebACLForResource", "waf-regional:GetWebACL", "waf-regional:AssociateWebACL", "waf-regional:DisassociateWebACL" ], "Resource": "*" } alb_policy_statement_json_7 = { "Effect": "Allow", "Action": ["tag:GetResources", "tag:TagResources"], "Resource": "*" } alb_policy_statement_json_8 = { "Effect": "Allow", "Action": ["waf:GetWebACL"], "Resource": "*" } alb_policy_statement_json_9 = { "Effect": "Allow", "Action": [ "wafv2:GetWebACL", "wafv2:GetWebACLForResource", "wafv2:AssociateWebACL", "wafv2:DisassociateWebACL" ], "Resource": "*" } alb_policy_statement_json_10 = { "Effect": "Allow", "Action": [ "shield:DescribeProtection", "shield:GetSubscriptionState", "shield:DeleteProtection", "shield:CreateProtection", "shield:DescribeSubscription", "shield:ListProtections" ], "Resource": "*" } # Attach the necessary permissions alb_service_account.add_to_policy( iam.PolicyStatement.from_json(alb_policy_statement_json_1)) alb_service_account.add_to_policy( iam.PolicyStatement.from_json(alb_policy_statement_json_2)) alb_service_account.add_to_policy( iam.PolicyStatement.from_json(alb_policy_statement_json_3)) alb_service_account.add_to_policy( iam.PolicyStatement.from_json(alb_policy_statement_json_4)) alb_service_account.add_to_policy( iam.PolicyStatement.from_json(alb_policy_statement_json_5)) alb_service_account.add_to_policy( iam.PolicyStatement.from_json(alb_policy_statement_json_6)) alb_service_account.add_to_policy( iam.PolicyStatement.from_json(alb_policy_statement_json_7)) alb_service_account.add_to_policy( iam.PolicyStatement.from_json(alb_policy_statement_json_8)) alb_service_account.add_to_policy( iam.PolicyStatement.from_json(alb_policy_statement_json_9)) alb_service_account.add_to_policy( iam.PolicyStatement.from_json(alb_policy_statement_json_10)) # Deploy the ALB Ingress Controller from the Helm chart eks_cluster.add_helm_chart( "aws-alb-ingress-controller", chart="aws-alb-ingress-controller", repository= "http://storage.googleapis.com/kubernetes-charts-incubator", namespace="kube-system", values={ "clusterName": "cluster", "awsRegion": os.environ["CDK_DEFAULT_REGION"], "awsVpcID": eks_vpc.vpc_id, "rbac": { "create": True, "serviceAccount": { "create": False, "name": "alb-ingress-controller" } } }) # Create code-server bastion # Get Latest Amazon Linux AMI amzn_linux = ec2.MachineImage.latest_amazon_linux( generation=ec2.AmazonLinuxGeneration.AMAZON_LINUX_2, edition=ec2.AmazonLinuxEdition.STANDARD, virtualization=ec2.AmazonLinuxVirt.HVM, storage=ec2.AmazonLinuxStorage.GENERAL_PURPOSE) # Create SecurityGroup for code-server security_group = ec2.SecurityGroup(self, "SecurityGroup", vpc=eks_vpc, allow_all_outbound=True) security_group.add_ingress_rule(ec2.Peer.any_ipv4(), ec2.Port.tcp(8080)) # Create our EC2 instance running CodeServer code_server_instance = ec2.Instance( self, "CodeServerInstance", instance_type=ec2.InstanceType("t3.large"), machine_image=amzn_linux, role=bastion_role, vpc=eks_vpc, vpc_subnets=ec2.SubnetSelection(subnet_type=ec2.SubnetType.PUBLIC), security_group=security_group, block_devices=[ ec2.BlockDevice(device_name="/dev/xvda", volume=ec2.BlockDeviceVolume.ebs(20)) ]) # Add UserData code_server_instance.user_data.add_commands( "mkdir -p ~/.local/lib ~/.local/bin ~/.config/code-server") code_server_instance.user_data.add_commands( "curl -fL https://github.com/cdr/code-server/releases/download/v3.5.0/code-server-3.5.0-linux-amd64.tar.gz | tar -C ~/.local/lib -xz" ) code_server_instance.user_data.add_commands( "mv ~/.local/lib/code-server-3.5.0-linux-amd64 ~/.local/lib/code-server-3.5.0" ) code_server_instance.user_data.add_commands( "ln -s ~/.local/lib/code-server-3.5.0/bin/code-server ~/.local/bin/code-server" ) code_server_instance.user_data.add_commands( "echo \"bind-addr: 0.0.0.0:8080\" > ~/.config/code-server/config.yaml" ) code_server_instance.user_data.add_commands( "echo \"auth: password\" >> ~/.config/code-server/config.yaml") code_server_instance.user_data.add_commands( "echo \"password: $(curl -s http://169.254.169.254/latest/meta-data/instance-id)\" >> ~/.config/code-server/config.yaml" ) code_server_instance.user_data.add_commands( "echo \"cert: false\" >> ~/.config/code-server/config.yaml") code_server_instance.user_data.add_commands( "~/.local/bin/code-server &") code_server_instance.user_data.add_commands( "yum -y install jq gettext bash-completion moreutils") code_server_instance.user_data.add_commands( "sudo pip install --upgrade awscli && hash -r") code_server_instance.user_data.add_commands( "echo 'export ALB_INGRESS_VERSION=\"v1.1.8\"' >> ~/.bash_profile") code_server_instance.user_data.add_commands( "curl --silent --location -o /usr/local/bin/kubectl \"https://amazon-eks.s3.us-west-2.amazonaws.com/1.17.9/2020-08-04/bin/linux/amd64/kubectl\"" ) code_server_instance.user_data.add_commands( "chmod +x /usr/local/bin/kubectl") code_server_instance.user_data.add_commands( "curl -L https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash" ) code_server_instance.user_data.add_commands( "export ACCOUNT_ID=$(aws sts get-caller-identity --output text --query Account)" ) code_server_instance.user_data.add_commands( "export AWS_REGION=$(curl -s 169.254.169.254/latest/dynamic/instance-identity/document | jq -r '.region')" ) code_server_instance.user_data.add_commands( "echo \"export ACCOUNT_ID=${ACCOUNT_ID}\" | tee -a ~/.bash_profile" ) code_server_instance.user_data.add_commands( "echo \"export AWS_REGION=${AWS_REGION}\" | tee -a ~/.bash_profile" ) code_server_instance.user_data.add_commands( "aws configure set default.region ${AWS_REGION}") code_server_instance.user_data.add_commands( "curl --silent --location https://rpm.nodesource.com/setup_12.x | bash -" ) code_server_instance.user_data.add_commands("yum -y install nodejs") code_server_instance.user_data.add_commands( "amazon-linux-extras enable python3") code_server_instance.user_data.add_commands( "yum install -y python3 --disablerepo amzn2-core") code_server_instance.user_data.add_commands("yum install -y git") code_server_instance.user_data.add_commands( "rm /usr/bin/python && ln -s /usr/bin/python3 /usr/bin/python && ln -s /usr/bin/pip3 /usr/bin/pip" ) code_server_instance.user_data.add_commands("npm install -g aws-cdk") code_server_instance.user_data.add_commands( "echo 'export KUBECONFIG=~/.kube/config' >> ~/.bash_profile") code_server_instance.user_data.add_commands( "git clone https://github.com/jasonumiker/eks-school.git") # Add ALB lb = elbv2.ApplicationLoadBalancer(self, "LB", vpc=eks_vpc, internet_facing=True) listener = lb.add_listener("Listener", port=80) listener.connections.allow_default_port_from_any_ipv4( "Open to the Internet") listener.connections.allow_to_any_ipv4( port_range=ec2.Port(string_representation="TCP 8080", protocol=ec2.Protocol.TCP, from_port=8080, to_port=8080)) listener.add_targets( "Target", port=8080, targets=[ elbv2.InstanceTarget( instance_id=code_server_instance.instance_id, port=8080) ])
def __init__(self, scope: core.Construct, id: str, **kwargs) -> None: super().__init__(scope, id, **kwargs) az1 = core.Fn.select(0, core.Fn.get_azs(region=core.Aws.REGION)) az2 = core.Fn.select(1, core.Fn.get_azs(region=core.Aws.REGION)) ########## # VPC ########## # VPC vpc = ec2.Vpc(self, "vpc", cidr="10.0.0.0/16", subnet_configuration=[]) # Internet gateway internet_gateway = ec2.CfnInternetGateway(self, "internet-gateway") ec2.CfnVPCGatewayAttachment(self, "internet_gateway_attatchment", vpc_id=vpc.vpc_id, internet_gateway_id=internet_gateway.ref) # Public Subnet az1 public_subnet_az1 = ec2.PublicSubnet(self, "subnet-public-1a", availability_zone=az1, cidr_block="10.0.0.0/24", vpc_id=vpc.vpc_id, map_public_ip_on_launch=True) public_subnet_az1.add_route("internet-gateway-route", router_id=internet_gateway.ref, router_type=ec2.RouterType.GATEWAY) # Public Subnet az2 public_subnet_az2 = ec2.PublicSubnet(self, "subnet-public-1c", availability_zone=az2, cidr_block="10.0.1.0/24", vpc_id=vpc.vpc_id, map_public_ip_on_launch=True) public_subnet_az2.add_route("internet-gateway-route", router_id=internet_gateway.ref, router_type=ec2.RouterType.GATEWAY) # Private Subnet az1 private_subnet_az1 = ec2.PrivateSubnet(self, "subnet-private-1a", availability_zone=az1, cidr_block="10.0.2.0/24", vpc_id=vpc.vpc_id) # Private Subnet az2 private_subnet_az2 = ec2.PrivateSubnet(self, "subnet-private-1c", availability_zone=az2, cidr_block="10.0.3.0/24", vpc_id=vpc.vpc_id) ########## # EC2 ########## # # EC2 Security Group ec2_security_group = ec2.SecurityGroup(self, "ec2-security-group", vpc=vpc) # ec2_security_group.add_ingress_rule(peer=ec2.Peer.any_ipv4(),connection=ec2.Port.tcp(80)) # User Data user_data = ec2.UserData.for_linux() user_data.add_commands( "yum -y update", "amazon-linux-extras install php7.2 -y", "yum -y install mysql httpd php-mbstring php-xml", "wget http://ja.wordpress.org/latest-ja.tar.gz -P /tmp/", "tar zxvf /tmp/latest-ja.tar.gz -C /tmp", "cp -r /tmp/wordpress/* /var/www/html/", "chown apache:apache -R /var/www/html", "systemctl enable httpd.service", "systemctl start httpd.service") # EC2 Instance instance_az1 = ec2.CfnInstance( self, "wordpress-instance-az1", subnet_id=public_subnet_az1.subnet_id, image_id=ec2.AmazonLinuxImage( generation=ec2.AmazonLinuxGeneration.AMAZON_LINUX_2).get_image( self).image_id, instance_type=ec2.InstanceType.of( instance_class=ec2.InstanceClass.BURSTABLE3, instance_size=ec2.InstanceSize.MICRO).to_string(), security_group_ids=[ec2_security_group.security_group_id], user_data=core.Fn.base64(user_data.render())) core.CfnOutput(self, "EC2 PublicDnsName", value=instance_az1.attr_public_dns_name) ########## # RDS ########## # RDS Security Group rds_security_group = ec2.SecurityGroup(self, "rds-security-group", vpc=vpc) ec2.CfnSecurityGroupIngress( self, "rds-security-group-ingress", group_id=rds_security_group.security_group_id, ip_protocol="tcp", from_port=3306, to_port=3306, source_security_group_id=ec2_security_group.security_group_id) # RDS Subnet Group rds_subnet_group = rds.CfnDBSubnetGroup( self, "rds-subnet-group", db_subnet_group_description="rds-subnet-group", subnet_ids=[ private_subnet_az1.subnet_id, private_subnet_az2.subnet_id ]) # RDS Instance rds_instance = rds.CfnDBInstance( self, "rds-instance", db_instance_identifier="wordpress-rds", engine=rds.DatabaseInstanceEngine.mysql( version=rds.MysqlEngineVersion.VER_8_0_20).engine_type, db_instance_class="db.t3.micro", master_username="******", master_user_password="******", db_name="wordpress", multi_az=False, vpc_security_groups=[rds_security_group.security_group_id], db_subnet_group_name=rds_subnet_group.ref, allocated_storage="20") core.CfnOutput(self, "RDS EndpointAddress", value=rds_instance.attr_endpoint_address) core.CfnOutput(self, "RDS EndpointPort", value=rds_instance.attr_endpoint_port) ########## # ALB ########## # ALB Security Group alb_security_group = ec2.SecurityGroup(self, "alb-security-group", vpc=vpc) alb_security_group.add_ingress_rule(peer=ec2.Peer.any_ipv4(), connection=ec2.Port.tcp(80)) # ALB Instance alb_instance = elb.ApplicationLoadBalancer( self, "alb", vpc=vpc, vpc_subnets=ec2.SubnetSelection( subnets=[public_subnet_az1, public_subnet_az2]), internet_facing=True, security_group=alb_security_group) # ALB Target Group alb_target_group = elb.ApplicationTargetGroup( self, "alb-target-group", vpc=vpc, target_type=elb.TargetType.INSTANCE, targets=[elb.InstanceTarget(instance_az1.ref)], protocol=elb.ApplicationProtocol.HTTP, port=80, health_check=elb.HealthCheck(protocol=elb.ApplicationProtocol.HTTP, path="/wp-includes/images/blank.gif")) # ALB Listener alb_listener = elb.ApplicationListener( self, "alb-listener", load_balancer=alb_instance, default_target_groups=[alb_target_group], protocol=elb.ApplicationProtocol.HTTP, port=80) core.CfnOutput(self, "ALB DNS Name", value=alb_instance.load_balancer_dns_name) # EC2 Security Group Ingress ec2.CfnSecurityGroupIngress( self, "ec2-security-group-ingress", group_id=ec2_security_group.security_group_id, ip_protocol="tcp", from_port=80, to_port=80, source_security_group_id=alb_security_group.security_group_id)
def __init__(self, stack: core.Stack, VPC: ec2.Vpc) -> None: bastionSG = ec2.SecurityGroup( stack, "BastionSecurityGroup", vpc=VPC, description="Allow ssh access to the bastion host", allow_all_outbound=True) bastionSG.add_ingress_rule(ec2.Peer.any_ipv4(), ec2.Port.tcp(22), '' "allow ssh access from the world") bastionSG.add_ingress_rule(ec2.Peer.any_ipv4(), ec2.Port.tcp_range(8081, 8083), "allow http(s) access from the world") userData = ec2.UserData.for_linux() userData.add_commands(""" set -v apt update apt install -y apt-transport-https ca-certificates curl gnupg-agent software-properties-common gdebi-core ec2-instance-connect curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" apt install -y docker-ce docker-ce-cli containerd.io usermod -a -G docker ubuntu curl -L "https://github.com/docker/compose/releases/download/1.26.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose chmod +x /usr/local/bin/docker-compose echo 'version: "3.8"' > /home/ubuntu/docker-compose.yaml echo 'services:' >> /home/ubuntu/docker-compose.yaml echo ' web:' >> /home/ubuntu/docker-compose.yaml echo ' image: %s/mtls-demo-web' >> /home/ubuntu/docker-compose.yaml echo ' network_mode: "service:proxy"' >> /home/ubuntu/docker-compose.yaml echo ' depends_on:' >> /home/ubuntu/docker-compose.yaml echo ' - proxy' >> /home/ubuntu/docker-compose.yaml echo ' restart: unless-stopped' >> /home/ubuntu/docker-compose.yaml echo ' proxy:' >> /home/ubuntu/docker-compose.yaml echo ' image: %s/mtls-demo-proxy' >> /home/ubuntu/docker-compose.yaml echo ' ports:' >> /home/ubuntu/docker-compose.yaml echo ' - "9901:9901"' >> /home/ubuntu/docker-compose.yaml echo ' - "8081:8081"' >> /home/ubuntu/docker-compose.yaml echo ' - "8082:8082"' >> /home/ubuntu/docker-compose.yaml echo ' - "8083:8083"' >> /home/ubuntu/docker-compose.yaml echo ' - "8084:8084"' >> /home/ubuntu/docker-compose.yaml echo ' restart: unless-stopped' >> /home/ubuntu/docker-compose.yaml echo 'networks:' >> /home/ubuntu/docker-compose.yaml echo ' public:' >> /home/ubuntu/docker-compose.yaml echo ' external: true' >> /home/ubuntu/docker-compose.yaml /usr/local/bin/docker-compose -f /home/ubuntu/docker-compose.yaml up """ % (stack.node.try_get_context("prefix"), stack.node.try_get_context("prefix"))) # no key installed, use # # aws ec2-instance-connect send-ssh-public-key # # to install a temporary key and gain access to the vm bastion = ec2.Instance( stack, "Bastion", instance_type=ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.MICRO), machine_image=ec2.MachineImage.lookup( name="ubuntu/images/hvm-ssd/ubuntu-bionic-18.04-amd64-server-*" ), vpc=VPC, security_group=bastionSG, vpc_subnets=ec2.SubnetSelection(subnet_type=ec2.SubnetType.PUBLIC), user_data=userData) core.CfnOutput(stack, "BastionIP", value=bastion.instance_public_ip) core.CfnOutput(stack, "BastionInstanceID", value=bastion.instance_id) core.CfnOutput( stack, "BastionSendSSHKeyCommand", value= "aws ec2-instance-connect send-ssh-public-key --instance-id %s --instance-os-user ubuntu --availability-zone %s --ssh-public-key file://~/.ssh/id_rsa.pub" % (bastion.instance_id, bastion.instance_availability_zone)) nlb = elbv2.NetworkLoadBalancer( stack, "NLB", vpc=VPC, internet_facing=True, vpc_subnets=ec2.SubnetSelection(subnet_type=ec2.SubnetType.PUBLIC)) core.CfnOutput(stack, "NLBAddress", value=nlb.load_balancer_dns_name) core.Tag.add(nlb, "stack", "ec2", apply_to_launched_instances=True) nlb.add_listener( "HTTP", port=80, default_target_groups=[ elbv2.NetworkTargetGroup( stack, "HTTPDefaultTargetGroup", port=8081, vpc=VPC, targets=[elbv2.InstanceTarget(bastion.instance_id, 8081)]) ]) nlb.add_listener( "mTLS", port=443, default_target_groups=[ elbv2.NetworkTargetGroup( stack, "mTLSDefaultTargetGroup", port=8083, vpc=VPC, targets=[elbv2.InstanceTarget(bastion.instance_id, 8083)]) ])
def __init__(self, scope: core.Construct, id: str, **kwargs) -> None: super().__init__(scope, id, **kwargs) code_server_vpc = ec2.Vpc(self, "VPC", cidr="10.0.0.0/16") # Create IAM Role For code-build code_server_role = iam.Role( self, "CodeServerRole", assumed_by=iam.CompositePrincipal( iam.ServicePrincipal("ec2.amazonaws.com")), managed_policies=[ iam.ManagedPolicy.from_aws_managed_policy_name( "AdministratorAccess") ]) # Create EC2 Instance Profile for that Role instance_profile = iam.CfnInstanceProfile( self, "InstanceProfile", roles=[code_server_role.role_name]) # Latest Amazon Linux AMI amzn_linux = ec2.MachineImage.latest_amazon_linux( generation=ec2.AmazonLinuxGeneration.AMAZON_LINUX_2, edition=ec2.AmazonLinuxEdition.STANDARD, virtualization=ec2.AmazonLinuxVirt.HVM, storage=ec2.AmazonLinuxStorage.GENERAL_PURPOSE) # Create SecurityGroup security_group = ec2.SecurityGroup(self, "SecurityGroup", vpc=code_server_vpc, allow_all_outbound=True) security_group.add_ingress_rule(ec2.Peer.any_ipv4(), ec2.Port.tcp(8080)) # Create our EC2 instance running CodeServer code_server_instance = ec2.Instance( self, "CodeServerInstance", instance_type=ec2.InstanceType("t3.large"), machine_image=amzn_linux, role=code_server_role, vpc=code_server_vpc, vpc_subnets=ec2.SubnetSelection(subnet_type=ec2.SubnetType.PUBLIC), security_group=security_group, block_devices=[ ec2.BlockDevice(device_name="/dev/xvda", volume=ec2.BlockDeviceVolume.ebs(20)) ]) # Add UserData code_server_instance.user_data.add_commands( "mkdir -p ~/.local/lib ~/.local/bin ~/.config/code-server") code_server_instance.user_data.add_commands( "curl -fL https://github.com/cdr/code-server/releases/download/v3.5.0/code-server-3.5.0-linux-amd64.tar.gz | tar -C ~/.local/lib -xz" ) code_server_instance.user_data.add_commands( "mv ~/.local/lib/code-server-3.5.0-linux-amd64 ~/.local/lib/code-server-3.5.0" ) code_server_instance.user_data.add_commands( "ln -s ~/.local/lib/code-server-3.5.0/bin/code-server ~/.local/bin/code-server" ) code_server_instance.user_data.add_commands( "echo \"bind-addr: 0.0.0.0:8080\" > ~/.config/code-server/config.yaml" ) code_server_instance.user_data.add_commands( "echo \"auth: password\" >> ~/.config/code-server/config.yaml") code_server_instance.user_data.add_commands( "echo \"password: $(curl -s http://169.254.169.254/latest/meta-data/instance-id)\" >> ~/.config/code-server/config.yaml" ) code_server_instance.user_data.add_commands( "echo \"cert: false\" >> ~/.config/code-server/config.yaml") code_server_instance.user_data.add_commands( "~/.local/bin/code-server &") # Add ALB lb = elbv2.ApplicationLoadBalancer(self, "LB", vpc=code_server_vpc, internet_facing=True) listener = lb.add_listener("Listener", port=80) listener.connections.allow_default_port_from_any_ipv4( "Open to the Internet") listener.connections.allow_to_any_ipv4( port_range=ec2.Port(string_representation="TCP 8080", protocol=ec2.Protocol.TCP, from_port=8080, to_port=8080)) listener.add_targets( "Target", port=8080, targets=[ elbv2.InstanceTarget( instance_id=code_server_instance.instance_id, port=8080) ])