def getAssociatedResources()

in WAF/WAF-Enhanced-Replicator/wafget.py [0:0]


def getAssociatedResources(wafClient, AclId, region, log, template, isRegional):
    '''
    Looks into the customer's WebACL and looks for associated resources.
    Returns a list of resources' names in case any is found.
    '''
    
    resourceString = ""
    resourcesList  = []
    
    # Checking if the Web ACL is associated with any resource. If the resulting array las a length greater than zero, 
    # it means there is at least one resource of that type associated with the Web ACL.
    # Looking for ALBs first. If at least one ALB is associated, we need to create all resources to support it:
    # VPC, Subnet, Route Table, Internet Gateway, Target Group and Security Group.
    if isRegional:
        try:
            rAlb = wafClient.list_resources_for_web_acl(WebACLId = AclId, ResourceType = "APPLICATION_LOAD_BALANCER")
        except:
            function.abort(log, template, "list_resources_for_web_acl(ALB)")
        if len(rAlb['ResourceArns']) > 0:
            log.write(function.getFormattedDateTime() + "Found at least one ALB associated with this Web ACL. Creating equivalent resource...\n")
            print("Found at least one ALB associated with this Web ACL. Creating equivalent resource...")
            resourceString += "resource \"aws_vpc\" \"waferVPC\" {\n"
            resourceString += "  cidr_block = \"10.10.0.0/16\"\n\n"
            resourceString += "  tags = {\n"
            resourceString += "    Name = \"WAFER\"\n"
            resourceString += "  }\n"
            resourceString += "}\n\n"

            resourceString += "resource \"aws_subnet\" \"waferSubnet1\" {\n"
            resourceString += "  vpc_id            = \"${aws_vpc.waferVPC.id}\"\n"
            resourceString += "  availability_zone = \"" + region + "a\"\n" 
            resourceString += "  cidr_block        = \"10.10.1.0/24\"\n\n"
            resourceString += "  tags = {\n"
            resourceString += "    Name = \"WAFER\"\n"
            resourceString += "  }\n"
            resourceString += "}\n\n"

            resourceString += "resource \"aws_subnet\" \"waferSubnet2\" {\n"
            resourceString += "  vpc_id            = \"${aws_vpc.waferVPC.id}\"\n"
            resourceString += "  availability_zone = \"" + region + "b\"\n" 
            resourceString += "  cidr_block        = \"10.10.2.0/24\"\n\n"
            resourceString += "  tags = {\n"
            resourceString += "    Name = \"WAFER\"\n"
            resourceString += "  }\n"
            resourceString += "}\n\n"

            resourceString += "resource \"aws_internet_gateway\" \"waferIGW\" {\n"
            resourceString += "  vpc_id = \"${aws_vpc.waferVPC.id}\"\n\n"
            resourceString += "  tags = {\n"
            resourceString += "    Name = \"WAFER\"\n"
            resourceString += "  }\n"
            resourceString += "}\n\n"

            resourceString += "resource \"aws_route_table\" \"waferRT\" {\n"
            resourceString += "  vpc_id     = \"${aws_vpc.waferVPC.id}\"\n\n"
            resourceString += "  route {\n"
            resourceString += "    cidr_block = \"0.0.0.0/0\"\n"
            resourceString += "    gateway_id = \"${aws_internet_gateway.waferIGW.id}\"\n"
            resourceString += "  }\n\n"
            resourceString += "  tags = {\n"
            resourceString += "    Name = \"WAFER\"\n"
            resourceString += "  }\n"
            resourceString += "}\n\n"

            resourceString += "resource \"aws_route_table_association\" \"waferRTAssociation1\" {\n"
            resourceString += "  subnet_id      = \"${aws_subnet.waferSubnet1.id}\"\n"
            resourceString += "  route_table_id = \"${aws_route_table.waferRT.id}\"\n"
            resourceString += "}\n\n"

            resourceString += "resource \"aws_route_table_association\" \"waferRTAssociation2\" {\n"
            resourceString += "  subnet_id      = \"${aws_subnet.waferSubnet2.id}\"\n"
            resourceString += "  route_table_id = \"${aws_route_table.waferRT.id}\"\n"
            resourceString += "}\n\n"
            
            resourceString += "resource \"aws_security_group\" \"waferALBSG\" {\n"
            resourceString += "  name        = \"waferALBSG\"\n"
            resourceString += "  description = \"Allow HTTP inbound traffic\"\n"
            resourceString += "  vpc_id      = \"${aws_vpc.waferVPC.id}\"\n"
            resourceString += "  ingress {\n"
            resourceString += "    from_port   = 80\n"
            resourceString += "    to_port     = 80\n"
            resourceString += "    protocol    = \"tcp\"\n"
            resourceString += "    cidr_blocks = [ \"0.0.0.0/0\" ]\n"
            resourceString += "  }\n\n"
            resourceString += "  egress {\n"
            resourceString += "    from_port   = 0\n"
            resourceString += "    to_port     = 0\n"
            resourceString += "    protocol    = \"-1\"\n"
            resourceString += "    cidr_blocks = [ \"0.0.0.0/0\" ]\n"
            resourceString += "  }\n\n"
            resourceString += "  tags = {\n"
            resourceString += "     Name = \"WAFER\"\n"
            resourceString += "  }\n"
            resourceString += "}\n\n"
            
            resourceString += "resource \"aws_lb\" \"waferALB\" {\n"
            resourceString += "  name               = \"waferALB\"\n"
            resourceString += "  internal           = false\n"
            resourceString += "  load_balancer_type = \"application\"\n"
            resourceString += "  security_groups    = [\"${aws_security_group.waferALBSG.id}\"]\n"
            resourceString += "  subnets            = [\"${aws_subnet.waferSubnet1.id}\", \"${aws_subnet.waferSubnet2.id}\"]\n\n"
            resourceString += "  enable_cross_zone_load_balancing = true\n\n"
            resourceString += "  tags = {\n"
            resourceString += "    Name = \"WAFER\"\n"
            resourceString += "  }\n"
            resourceString += "}\n\n"

            resourceString += "resource \"aws_lb_target_group\" \"waferALBTG\" {\n"
            resourceString += "  name     = \"waferALBTG\"\n"
            resourceString += "  port     = 80\n"
            resourceString += "  protocol = \"HTTP\"\n"
            resourceString += "  vpc_id   = \"${aws_vpc.waferVPC.id}\"\n"
            resourceString += "}\n\n"

            resourceString += "resource \"aws_lb_listener\" \"waferALBListener\" {\n"
            resourceString += "  load_balancer_arn = \"${aws_lb.waferALB.arn}\"\n"
            resourceString += "  port     = \"80\"\n"
            resourceString += "  protocol = \"HTTP\"\n\n"
            resourceString += "  default_action {\n"
            resourceString += "    type             = \"forward\"\n"
            resourceString += "    target_group_arn = \"${aws_lb_target_group.waferALBTG.arn}\"\n"
            resourceString += "  }\n"
            resourceString += "}\n\n"
            
            listTemp = []
            listTemp.append("ALB_DNS_Name")
            listTemp.append("ALB DNS Name")
            listTemp.append("aws_lb.waferALB.dns_name")
            resourcesList.append(listTemp)
        # Let's check also if there's an API Gateway endpoint associated with the Web ACL.
        try:
            rApi = wafClient.list_resources_for_web_acl(WebACLId = AclId, ResourceType = "API_GATEWAY")
        except:
            function.abort(log, template, "list_resources_for_web_acl(API)")
        if len(rApi['ResourceArns']) > 0:
            log.write(function.getFormattedDateTime() + "Found at least one API Gateway endpoint associated with this Web ACL. Creating equivalent resource...\n")
            log.write(function.getFormattedDateTime() + "Do not forget to change the API Gateway Integration method type to something different than 'MOCK'!\n")
            print("Found at least one API Gateway endpoint associated with this Web ACL. Creating equivalent resource...")
            resourceString += "resource \"aws_api_gateway_rest_api\" \"waferAPI\" {\n"
            resourceString += "  name        = \"waferAPI\"\n"
            resourceString += "  description = \"WAFER API\"\n"
            resourceString += "}\n\n"

            resourceString += "resource \"aws_api_gateway_resource\" \"waferAPIResource\" {\n"
            resourceString += "  rest_api_id = \"${aws_api_gateway_rest_api.waferAPI.id}\"\n"
            resourceString += "  parent_id   = \"${aws_api_gateway_rest_api.waferAPI.root_resource_id}\"\n"
            resourceString += "  path_part   = \"WAFER\"\n"
            resourceString += "}\n\n"

            resourceString += "resource \"aws_api_gateway_method\" \"waferMethod\" {\n"
            resourceString += "  rest_api_id   = \"${aws_api_gateway_rest_api.waferAPI.id}\"\n"
            resourceString += "  resource_id   = \"${aws_api_gateway_resource.waferAPIResource.id}\"\n"
            resourceString += "  http_method   = \"GET\"\n"
            resourceString += "  authorization = \"NONE\"\n"
            resourceString += "}\n\n"

            resourceString += "resource \"aws_api_gateway_deployment\" \"waferDeployment\" {\n"
            resourceString += "  depends_on  = [\"aws_api_gateway_integration.waferIntegration\"]\n"
            resourceString += "  rest_api_id = \"${aws_api_gateway_rest_api.waferAPI.id}\"\n"
            resourceString += "  stage_name  = \"test\"\n"
            resourceString += "}\n\n"

            resourceString += "resource \"aws_api_gateway_stage\" \"waferStage\" {\n"
            resourceString += "  stage_name    = \"waferStage\"\n"
            resourceString += "  rest_api_id   = \"${aws_api_gateway_rest_api.waferAPI.id}\"\n"
            resourceString += "  deployment_id = \"${aws_api_gateway_deployment.waferDeployment.id}\"\n"
            resourceString += "}\n\n"

            resourceString += "resource \"aws_api_gateway_integration\" \"waferIntegration\" {\n"
            resourceString += "  rest_api_id             = \"${aws_api_gateway_rest_api.waferAPI.id}\"\n"
            resourceString += "  resource_id             = \"${aws_api_gateway_resource.waferAPIResource.id}\"\n"
            resourceString += "  http_method             = \"${aws_api_gateway_method.waferMethod.http_method}\"\n"
            resourceString += "  integration_http_method = \"GET\"\n"
            resourceString += "  type                    = \"MOCK\"\n"
            resourceString += "}\n\n"
            
            listTemp = []
            listTemp.append("API_Gateway_Invoke_URL")
            listTemp.append("API Gateway Invoke URL")
            listTemp.append("aws_api_gateway_stage.waferStage.invoke_url")
            resourcesList.append(listTemp)
    else:
        # It's a global WAF, so, we can check if there's a CloudFront distribution associated with the Web ACL.
        try:
            cloudFront = boto3.client('cloudfront')
            rCfn = cloudFront.list_distributions_by_web_acl_id(WebACLId = AclId)
        except:
            function.abort(log, template, "list_distributions_by_web_acl_id(CloudFront)")
        if rCfn['DistributionList']['Quantity'] > 0:
            log.write(function.getFormattedDateTime() + "Found at least one CloudFront distribution associated with this Web ACL. Creating equivalent resource...\n")
            print("Found at least one CloudFront distribution associated with this Web ACL. Creating equivalent resource...")
            # We need to create an ALB first and then use it as the origin for the CloudFront distribution.
            resourceString += "resource \"aws_vpc\" \"waferVPC\" {\n"
            resourceString += "  cidr_block = \"10.10.0.0/16\"\n\n"
            resourceString += "  tags = {\n"
            resourceString += "    Name = \"WAFER\"\n"
            resourceString += "  }\n"
            resourceString += "}\n\n"

            resourceString += "resource \"aws_subnet\" \"waferSubnet1\" {\n"
            resourceString += "  vpc_id            = \"${aws_vpc.waferVPC.id}\"\n"
            resourceString += "  availability_zone = \"us-east-1a\"\n" 
            resourceString += "  cidr_block        = \"10.10.1.0/24\"\n\n"
            resourceString += "  tags = {\n"
            resourceString += "    Name = \"WAFER\"\n"
            resourceString += "  }\n"
            resourceString += "}\n\n"

            resourceString += "resource \"aws_subnet\" \"waferSubnet2\" {\n"
            resourceString += "  vpc_id            = \"${aws_vpc.waferVPC.id}\"\n"
            resourceString += "  availability_zone = \"us-east-1b\"\n" 
            resourceString += "  cidr_block        = \"10.10.2.0/24\"\n\n"
            resourceString += "  tags = {\n"
            resourceString += "    Name = \"WAFER\"\n"
            resourceString += "  }\n"
            resourceString += "}\n\n"

            resourceString += "resource \"aws_internet_gateway\" \"waferIGW\" {\n"
            resourceString += "  vpc_id = \"${aws_vpc.waferVPC.id}\"\n\n"
            resourceString += "  tags = {\n"
            resourceString += "    Name = \"WAFER\"\n"
            resourceString += "  }\n"
            resourceString += "}\n\n"

            resourceString += "resource \"aws_route_table\" \"waferRT\" {\n"
            resourceString += "  vpc_id     = \"${aws_vpc.waferVPC.id}\"\n\n"
            resourceString += "  route {\n"
            resourceString += "    cidr_block = \"0.0.0.0/0\"\n"
            resourceString += "    gateway_id = \"${aws_internet_gateway.waferIGW.id}\"\n"
            resourceString += "  }\n\n"
            resourceString += "  tags = {\n"
            resourceString += "    Name = \"WAFER\"\n"
            resourceString += "  }\n"
            resourceString += "}\n\n"

            resourceString += "resource \"aws_route_table_association\" \"waferRTAssociation1\" {\n"
            resourceString += "  subnet_id      = \"${aws_subnet.waferSubnet1.id}\"\n"
            resourceString += "  route_table_id = \"${aws_route_table.waferRT.id}\"\n"
            resourceString += "}\n\n"

            resourceString += "resource \"aws_route_table_association\" \"waferRTAssociation2\" {\n"
            resourceString += "  subnet_id      = \"${aws_subnet.waferSubnet2.id}\"\n"
            resourceString += "  route_table_id = \"${aws_route_table.waferRT.id}\"\n"
            resourceString += "}\n\n"
            
            resourceString += "resource \"aws_security_group\" \"waferALBSG\" {\n"
            resourceString += "  name        = \"waferALBSG\"\n"
            resourceString += "  description = \"Allow HTTP inbound traffic\"\n"
            resourceString += "  vpc_id      = \"${aws_vpc.waferVPC.id}\"\n"
            resourceString += "  ingress {\n"
            resourceString += "    from_port   = 80\n"
            resourceString += "    to_port     = 80\n"
            resourceString += "    protocol    = \"tcp\"\n"
            resourceString += "    cidr_blocks = [ \"0.0.0.0/0\" ]\n"
            resourceString += "  }\n\n"
            resourceString += "  egress {\n"
            resourceString += "    from_port   = 0\n"
            resourceString += "    to_port     = 0\n"
            resourceString += "    protocol    = \"-1\"\n"
            resourceString += "    cidr_blocks = [ \"0.0.0.0/0\" ]\n"
            resourceString += "  }\n\n"
            resourceString += "  tags = {\n"
            resourceString += "     Name = \"WAFER\"\n"
            resourceString += "  }\n"
            resourceString += "}\n\n"
            
            resourceString += "resource \"aws_lb\" \"waferALB\" {\n"
            resourceString += "  name               = \"waferALB\"\n"
            resourceString += "  internal           = false\n"
            resourceString += "  load_balancer_type = \"application\"\n"
            resourceString += "  security_groups    = [\"${aws_security_group.waferALBSG.id}\"]\n"
            resourceString += "  subnets            = [\"${aws_subnet.waferSubnet1.id}\", \"${aws_subnet.waferSubnet2.id}\"]\n\n"
            resourceString += "  enable_cross_zone_load_balancing = true\n\n"
            resourceString += "  tags = {\n"
            resourceString += "    Name = \"WAFER\"\n"
            resourceString += "  }\n"
            resourceString += "}\n\n"

            resourceString += "resource \"aws_lb_target_group\" \"waferALBTG\" {\n"
            resourceString += "  name     = \"waferALBTG\"\n"
            resourceString += "  port     = 80\n"
            resourceString += "  protocol = \"HTTP\"\n"
            resourceString += "  vpc_id   = \"${aws_vpc.waferVPC.id}\"\n"
            resourceString += "}\n\n"

            resourceString += "resource \"aws_lb_listener\" \"waferALBListener\" {\n"
            resourceString += "  load_balancer_arn = \"${aws_lb.waferALB.arn}\"\n"
            resourceString += "  port     = \"80\"\n"
            resourceString += "  protocol = \"HTTP\"\n\n"
            resourceString += "  default_action {\n"
            resourceString += "    type             = \"forward\"\n"
            resourceString += "    target_group_arn = \"${aws_lb_target_group.waferALBTG.arn}\"\n"
            resourceString += "  }\n"
            resourceString += "}\n\n"
            
            listTemp = []
            listTemp.append("ALB_DNS_Name")
            listTemp.append("ALB DNS Name")
            listTemp.append("aws_lb.waferALB.dns_name")
            resourcesList.append(listTemp)
            
            # Time to create the CloudFront distribution.
            resourceString += "resource \"aws_cloudfront_distribution\" \"waferCFN\" {\n"
            resourceString += "  comment    = \"WAFER CloudFront Distribution\"\n"
            resourceString += "  enabled    = true\n"
            resourceString += "  web_acl_id = \"${aws_waf_web_acl.web_acl.id}\"\n\n"
            resourceString += "  origin {\n"
            resourceString += "    domain_name = \"${aws_lb.waferALB.dns_name}\"\n"
            resourceString += "    origin_id   = \"ELB-${aws_lb.waferALB.name}\"\n\n"
            resourceString += "    custom_origin_config {\n"
            resourceString += "      http_port              = 80\n"
            resourceString += "      https_port             = 443\n"
            resourceString += "      origin_protocol_policy = \"http-only\"\n"
            resourceString += "      origin_ssl_protocols   = [\"TLSv1\", \"TLSv1.1\", \"TLSv1.2\", \"SSLv3\"]\n"
            resourceString += "    }\n"
            resourceString += "  }\n\n"
            resourceString += "  default_cache_behavior {\n"
            resourceString += "    allowed_methods  = [\"GET\", \"HEAD\", \"OPTIONS\", \"PUT\", \"POST\", \"PATCH\", \"DELETE\"]\n"
            resourceString += "    cached_methods   = [\"GET\", \"HEAD\"]\n"
            resourceString += "    target_origin_id = \"ELB-${aws_lb.waferALB.name}\"\n\n"
            resourceString += "    forwarded_values {\n"
            resourceString += "      query_string = true\n"
            resourceString += "      headers      = [\"*\"]\n"
            resourceString += "      cookies {\n"
            resourceString += "        forward = \"all\"\n"
            resourceString += "      }\n"
            resourceString += "    }\n\n"
            resourceString += "    viewer_protocol_policy = \"allow-all\"\n"
            resourceString += "  }\n\n"
            resourceString += "  viewer_certificate {\n"
            resourceString += "    cloudfront_default_certificate = true\n"
            resourceString += "  }\n\n"
            resourceString += "  restrictions {\n"
            resourceString += "    geo_restriction {\n"
            resourceString += "      restriction_type = \"none\"\n"
            resourceString += "    }\n"
            resourceString += "  }\n"
            resourceString += "}\n\n"

            listTemp = []
            listTemp.append("CloudFront_Distribution_Domain_Name")
            listTemp.append("CloudFront Distribution Name")
            listTemp.append("aws_cloudfront_distribution.waferCFN.domain_name")
            resourcesList.append(listTemp)

    return([resourcesList, resourceString])