from aws_cdk import ( aws_ec2 as ec2, aws_ecs as ecs, aws_ecr as ecr, aws_iam as iam, aws_logs as logs, aws_elasticloadbalancingv2 as elbv2, aws_route53 as route53, aws_route53_targets, core, ) from .ecs_stack import EcsStack class VpcStack(core.Stack): def __init__(self, scope: core.Construct, id: str, props, **kwargs) -> None: super().__init__(scope, id, **kwargs) vpn_connection = ec2.Peer.ipv4( '0.0.0.0/16' ) # Props Setup stage = scope.node.try_get_context('stage') my_service_name = scope.node.try_get_context('serviceName') region = scope.node.try_get_context(stage)['region'] account = scope.node.try_get_context(stage)['account'] # Setup IAM user for logs vpc_flow_role = iam.Role( self, 'FlowLog', assumed_by=iam.ServicePrincipal('vpc-flow-logs.amazonaws.com') ) # Create Cloudwatch log group log_group = logs.LogGroup( self, 'LogGroup', log_group_name=my_service_name, retention=logs.RetentionDays('ONE_YEAR'), removal_policy=core.RemovalPolicy('DESTROY') ) # Setup VPC resource vpc = ec2.Vpc( self, '{0}-{1}-vpc'.format(my_service_name, stage), cidr=props['cidr'], max_azs=props['vpcAzCount'] ) # Setup VPC flow logs vpc_log = ec2.CfnFlowLog( self, 'FlowLogs', resource_id=vpc.vpc_id, resource_type='VPC', traffic_type='ALL', deliver_logs_permission_arn=vpc_flow_role.role_arn, log_destination_type='cloud-watch-logs', log_group_name=log_group.log_group_name ) # Setup Security Group in VPC vpc_sg = ec2.SecurityGroup( self, 'EcSSG', vpc=vpc, allow_all_outbound=None, description="Security Group for vpc", security_group_name="{0}-{1}-vpc-sg".format(my_service_name, stage) ) # Add Rules to Security Group vpc_sg.add_ingress_rule( peer=pearson_vpn_connection, connection=ec2.Port.tcp(22) ) # ALB Security Group alb_sg = ec2.SecurityGroup( self, 'AlbSG', vpc=vpc, allow_all_outbound=None, description="Security group for ALB", security_group_name="{0}-{1}-alb-sg".format(my_service_name,stage) ) alb_sg.add_ingress_rule( peer=vpn_connection, connection=ec2.Port.tcp(443) ) # Setup ALB alb = elbv2.ApplicationLoadBalancer( self,'ALB', vpc=vpc, internet_facing=True, security_group=alb_sg ) core.CfnOutput(self, 'VPCId', value=vpc.vpc_id ) # ECS Execution Role - Grants ECS agent to call AWS APIs ecs_execution_role = iam.Role( self, 'ECSExecutionRole', assumed_by=iam.ServicePrincipal('ecs-tasks.amazonaws.com'), role_name="{0}-{1}-execution-role".format(my_service_name, stage) ) # Setup Role Permissions ecs_execution_role.add_to_policy( iam.PolicyStatement( effect=iam.Effect.ALLOW, actions=[ 'elasticloadbalancing:DeregisterInstancesFromLoadBalancer', 'elasticloadbalancing:DeregisterTargets', 'elasticloadbalancing:Describe*', 'elasticloadbalancing:RegisterInstancesWithLoadBalancer', 'elasticloadbalancing:RegisterTargets', 'ec2:Describe*', 'ec2:AuthorizeSecurityGroupIngress', 'sts:AssumeRole', 'ssm:GetParameters' ], resources=["*"] ) ) # ECS Task Role - Grants containers in task permission to AWS APIs ecs_task_role = iam.Role( self, 'ECSTaskRole', assumed_by=iam.ServicePrincipal('ecs-tasks.amazonaws.com'), role_name="{0}-{1}-task-role".format(my_service_name, stage) ) # Setup Role Permissions ecs_task_role.add_to_policy( iam.PolicyStatement( effect=iam.Effect.ALLOW, actions=[ 'ecr:GetAuthorizationToken', 'ecr:BatchCheckLayerAvailability', 'ecr:GetDownloadUrlForLayer', 'ecr:BatchGetImage', 'logs:CreateLogStream', 'logs:PutLogEvents', 'dynamodb:Query', 'dynamodb:ListTables' ], resources=["*"] ) ) EcsStack(self, "{0}-{1}-ecs".format( my_service_name, stage ), props=props, vpc=vpc, execution_role=ecs_execution_role, task_role=ecs_task_role, log_group=log_group, env={ 'region': region, 'account': account } )