Пример #1
0
    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
Пример #2
0
    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))
Пример #3
0
    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])
Пример #4
0
    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)
            ])
Пример #5
0
    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)
Пример #6
0
    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)
            ])