AWSTemplateFormatVersion: 2010-09-09 Description: Serverless (API Gateway) website that returns AWS IP prefixes from ip-ranges.json ( https://github.com/aws-samples/aws-ipranges-api ) Metadata: License: Description: > Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. SPDX-License-Identifier: MIT-0 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. AWS::CloudFormation::Interface: ParameterGroups: - Label: default: HTTP API Parameters: - awsServices - allowNetworks - Label: default: Lambda Parameters: - pythonRuntime - cpuArchitecture - lambdaFunctionName - lambdaAuthorizerFunctionName - Label: default: "[Optional] Custom domain name" Parameters: - customDomainName - certificateArn - disableDefaultEndPoint ParameterLabels: awsServices: default: "[Services]: Default AWS Service IP prefixes to return separated by commas ( https://docs.aws.amazon.com/vpc/latest/userguide/aws-ip-ranges.html#aws-ip-syntax )" allowNetworks: default: "[Allowed Networks]: Allowed source IP prefixes separated by commas (e.g. 1.2.3.4/32,100.0.0.0/24). Get your IP from https://checkip.amazonaws.com " pythonRuntime: default: Python 3 runtime version ( https://docs.aws.amazon.com/lambda/latest/dg/lambda-python.html ) cpuArchitecture: default: Instruction set architecture lambdaFunctionName: default: Unique Lambda function name lambdaAuthorizerFunctionName: default: Unique Lambda authorizer function name customDomainName: default: "Custom domain name to use (e.g. api.example.com)" certificateArn: default: "ARN of certificate (e.g. arn:aws:acm:::certificate/). Get ARN from https://console.aws.amazon.com/acm/home?#/certificates/list" disableDefaultEndPoint: default: "Disable default endpoint" Parameters: awsServices: Type: CommaDelimitedList AllowedValues: - AMAZON - AMAZON_APPFLOW - AMAZON_CONNECT - API_GATEWAY - CHIME_MEETINGS - CHIME_VOICECONNECTOR - CLOUD9 - CLOUDFRONT - CLOUDFRONT_ORIGIN_FACING - CODEBUILD - DYNAMODB - EBS - EC2 - EC2_INSTANCE_CONNECT - GLOBALACCELERATOR - KINESIS_VIDEO_STREAMS - MEDIA_PACKAGE_V2 - ROUTE53 - ROUTE53_HEALTHCHECKS - ROUTE53_HEALTHCHECKS_PUBLISHING - ROUTE53_RESOLVER - S3 - WORKSPACES_GATEWAYS Default: CLOUDFRONT_ORIGIN_FACING ConstraintDescription: Enter a valid AWS service allowNetworks: Type: String Default: 0.0.0.0/0 lambdaFunctionName: Type: String AllowedPattern: "[a-zA-Z0-9]+[a-zA-Z0-9-]+[a-zA-Z0-9]+" ConstraintDescription: Enter a valid function name Default: aws-ipranges-api lambdaAuthorizerFunctionName: Type: String AllowedPattern: "[a-zA-Z0-9]+[a-zA-Z0-9-]+[a-zA-Z0-9]+" ConstraintDescription: Enter a valid function name Default: aws-ipranges-api-authorizer pythonRuntime: Type: String AllowedPattern: "python3\\.\\d{1,2}" ConstraintDescription: Enter a valid Python version Default: python3.12 cpuArchitecture: Type: String AllowedValues: - x86_64 - arm64 Default: arm64 customDomainName: Type: String Default: "" certificateArn: Type: String Default: "" disableDefaultEndPoint: Type: String AllowedValues: - true - false Default: false Conditions: useCustomDomainName: !And [ !Not [!Equals [!Ref customDomainName, ""]], !Not [!Equals [!Ref certificateArn, ""]], ] enableDefaultEndPoint: !Equals [!Ref disableDefaultEndPoint, "false"] Resources: lambdaFunctionIamRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - sts:AssumeRole Policies: # Access logs at https://docs.aws.amazon.com/lambda/latest/operatorguide/access-logs.html - PolicyName: lambdaFunctionPolicy PolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Action: - logs:CreateLogStream - logs:PutLogEvents Resource: !Sub arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/${lambdaFunctionName}:* Tags: - Key: StackName Value: !Sub ${AWS::StackName} - Key: StackId Value: !Sub ${AWS::StackId} - Key: GitHub Value: https://github.com/aws-samples/aws-ipranges-api - Key: Description Value: !Sub For lambda function ${lambdaFunctionName} lambdaFunctionLogGroup: Type: AWS::Logs::LogGroup DeletionPolicy: Delete UpdateReplacePolicy: Delete Properties: KmsKeyId: !Ref AWS::NoValue RetentionInDays: !Ref AWS::NoValue LogGroupName: !Sub /aws/lambda/${lambdaFunctionName} Tags: - Key: StackName Value: !Sub ${AWS::StackName} - Key: StackId Value: !Sub ${AWS::StackId} - Key: GitHub Value: https://github.com/aws-samples/aws-ipranges-api lambdaFunction: Type: AWS::Lambda::Function Properties: Description: !Sub "[${AWS::StackName}] - Returns AWS IP prefixes for API Gateway" FunctionName: !Ref lambdaFunctionName Handler: "index.lambda_handler" MemorySize: 1769 ReservedConcurrentExecutions: !Ref AWS::NoValue Role: !GetAtt lambdaFunctionIamRole.Arn Environment: Variables: SERVICES: !Join [",", !Ref awsServices] Runtime: !Ref pythonRuntime Timeout: 25 Architectures: - !Ref cpuArchitecture Code: ZipFile: | # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. # SPDX-License-Identifier: MIT-0 import os import json from urllib import request import ipaddress # AWS services to return for default API default_services = os.getenv('SERVICES', 'CLOUDFRONT_ORIGIN_FACING').split(',') if default_services == ['']: default_services = ['CLOUDFRONT_ORIGIN_FACING'] # Search function: check if valid IP address def is_ipAddress(address): try: ipaddress.ip_address(address) return True except ValueError: return False def is_ipv4(address): try: ipaddress.IPv4Address(address) return True except ValueError: return False # See https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-lambda.html for payload format def lambda_handler(event, context): # load ip-ranges.json response = request.urlopen('https://ip-ranges.amazonaws.com/ip-ranges.json') data = response.read() ipranges_json = json.loads(data) createDate = ipranges_json['createDate'] syncToken = ipranges_json['syncToken'] url = event['requestContext']['http']['path'] if url.lower() == '/favicon.ico': return { 'statusCode': 404, 'body': 'Not Found!', "headers": { "content-type": "text/html" } } elif url.lower() == '/robots.txt': return { 'statusCode': 200, 'body' : 'User-agent: *\nDisallow: /', "headers": { "content-type": "text/plain" } } elif url.lower() == '/createdate': return { 'statusCode': 200, 'body' : createDate, "headers": { "content-type": "text/plain" } } elif url.lower() == '/synctoken': return { 'statusCode': 200, 'body' : syncToken, "headers": { "content-type": "text/plain" } } # available aws services/regions/network_border_groups all_aws_services = list() all_aws_regions = list() all_aws_networks = list() for i in ipranges_json['prefixes']: if i['service'] not in all_aws_services: all_aws_services.append(i['service']) if i['region'] not in all_aws_regions: all_aws_regions.append(i['region']) if i['network_border_group'] not in all_aws_networks: all_aws_networks.append(i['network_border_group']) args = url.split('/') responseBody = '' # SERVICES and REGIONS to filter by? SERVICES = all_aws_services.copy() REGIONS = all_aws_regions.copy() NETWORKS = all_aws_networks.copy() # return list of all prefixes / services / regions / network_border_groups if len(args) == 2: SERVICES = default_services if args[1].upper() == 'SERVICE': responseBody = all_aws_services elif args[1].upper() == 'REGION': responseBody = all_aws_regions elif args[1].upper() == 'NETWORK': responseBody = all_aws_networks elif args[1].upper() == "SEARCH": responseBody = list() responseBody.append("Enter a IP address to query") if responseBody != '': return { 'statusCode': 200, 'body': '\n'.join(sorted(responseBody)), "headers": { "content-type": "text/plain", "path" : url, "syncToken": ipranges_json['syncToken'], "createDate": ipranges_json['createDate'] } } elif len(args) >= 3: # /SERVICE// if args[1].upper()=='SERVICE' and args[2] in all_aws_services: SERVICES = [args[2]] if len(args) >=4 and args[3] in all_aws_regions: REGIONS = [args[3]] # /REGION// elif args[1].upper()=='REGION' and args[2] in all_aws_regions: REGIONS = [args[2]] if len(args) >=4 and args[3] in all_aws_services: SERVICES= [args[3]] # /NETWORK// elif args[1].upper()=='NETWORK' and args[2] in all_aws_networks: NETWORKS = [args[2]] if len(args) >=4 and args[3] in all_aws_services: SERVICES= [args[3]] # /SEARCH/ elif args[1].upper() == 'SEARCH' and is_ipAddress(args[2]): aws_ranges = list() ip_object = ipaddress.ip_address(args[2]) if is_ipv4(args[2]): for i in ipranges_json['prefixes']: if ip_object in ipaddress.ip_network(i['ip_prefix']): aws_ranges.append(i['ip_prefix'] + "," + i['region'] + "," + i["service"] + "," + i["network_border_group"]) else: for i in ipranges_json['ipv6_prefixes']: if ip_object in ipaddress.ip_network(i['ipv6_prefix']): aws_ranges.append(i['ipv6_prefix'] + "," + i['region'] + "," + i["service"] + "," + i["network_border_group"]) if len(aws_ranges) > 0: aws_ranges.insert(0, 'ip_prefix,region,service,network_border_group') return { 'statusCode': 200, 'body': '\n'.join(aws_ranges), "headers": { "content-type": "text/plain", "path" : url, "syncToken": ipranges_json['syncToken'], "createDate": ipranges_json['createDate'] } } else: return { 'statusCode': 404, 'body': 'Not AWS IP address', "headers": { "content-type": "text/html" } } else: return { 'statusCode': 404, 'body': 'Not Found!', "headers": { "content-type": "text/html" } } # IPv4 / IPv6 only? : ipv4_only = url.upper().endswith('/IPV4.TXT') ipv6_only = url.upper().endswith('/IPV6.TXT') prefixes = '' aws_region = list() aws_service = list() aws_network = list() ipv4_prefixes = list() if not ipv6_only: for i in ipranges_json['prefixes']: if i['service'] in SERVICES and i['region'] in REGIONS and i['network_border_group'] in NETWORKS and i['ip_prefix'] not in ipv4_prefixes: ipv4_prefixes.append(i['ip_prefix']) if i['region'] not in aws_region: aws_region.append(i['region']) if i['service'] not in aws_service: aws_service.append(i['service']) if i['network_border_group'] not in aws_network: aws_network.append(i['network_border_group']) prefixes = '\n'.join(sorted(ipv4_prefixes, key = ipaddress.IPv4Network)) ipv6_prefixes = list() if not ipv4_only: for i in ipranges_json['ipv6_prefixes']: if i['service'] in SERVICES and i['region'] in REGIONS and i['network_border_group'] in NETWORKS and i['ipv6_prefix'] not in ipv6_prefixes: ipv6_prefixes.append(i['ipv6_prefix']) if i['region'] not in aws_region: aws_region.append(i['region']) if i['service'] not in aws_service: aws_service.append(i['service']) if i['network_border_group'] not in aws_network: aws_network.append(i['network_border_group']) if len(prefixes) > 0: prefixes += '\n' prefixes += '\n'.join(sorted(ipv6_prefixes, key = ipaddress.IPv6Network)) sourceIp = event['requestContext']['http']['sourceIp'] print(f'Source IP:{sourceIp}, Path:{url}, IPv4 Prefixes:{len(ipv4_prefixes)}, IPv6 Prefixes:{len(ipv6_prefixes)}, createDate:{createDate}, syncToken:{syncToken}') return { 'statusCode': 200, 'body': prefixes, "headers": { "content-type": "text/plain", "aws-service" : ','.join(sorted(aws_service)), "aws-region" : ','.join(sorted(aws_region)), "aws-network" : ','.join(sorted(aws_network)), "path" : url, "syncToken": syncToken, "createDate": createDate } } Tags: - Key: StackName Value: !Sub ${AWS::StackName} - Key: StackId Value: !Sub ${AWS::StackId} - Key: GitHub Value: https://github.com/aws-samples/aws-ipranges-api - Key: Description Value: Returns AWS IP prefixes from ip-ranges.json lambdaVersion: Type: AWS::Lambda::Version Properties: FunctionName: !Ref lambdaFunction Description: Version 1.0 lambdaAuthorizerFunctionIamRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - sts:AssumeRole Policies: - PolicyName: lambdaAuthorizerFunctionPolicy PolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Action: - logs:CreateLogStream - logs:PutLogEvents Resource: !Sub arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/${lambdaAuthorizerFunctionName}:* Tags: - Key: StackName Value: !Sub ${AWS::StackName} - Key: StackId Value: !Sub ${AWS::StackId} - Key: GitHub Value: https://github.com/aws-samples/aws-ipranges-api - Key: Description Value: !Sub For lambda function ${lambdaAuthorizerFunctionName} lambdaAuthorizerFunctionLogGroup: Type: AWS::Logs::LogGroup DeletionPolicy: Delete UpdateReplacePolicy: Delete Properties: KmsKeyId: !Ref AWS::NoValue RetentionInDays: !Ref AWS::NoValue LogGroupName: !Sub /aws/lambda/${lambdaAuthorizerFunction} Tags: - Key: StackName Value: !Sub ${AWS::StackName} - Key: StackId Value: !Sub ${AWS::StackId} - Key: GitHub Value: https://github.com/aws-samples/aws-ipranges-api lambdaAuthorizerFunction: Type: AWS::Lambda::Function Properties: Description: !Sub "[${AWS::StackName}] - Lambda Authorizer for API Gateway" FunctionName: !Ref lambdaAuthorizerFunctionName Handler: "index.lambda_handler" MemorySize: 128 ReservedConcurrentExecutions: !Ref AWS::NoValue Role: !GetAtt lambdaAuthorizerFunctionIamRole.Arn Environment: Variables: ALLOWED_NETWORKS: !Ref allowNetworks Runtime: !Ref pythonRuntime Timeout: 5 Architectures: - !Ref cpuArchitecture Code: ZipFile: | # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. # SPDX-License-Identifier: MIT-0 import os import ipaddress # Allowed source IP prefixes allowed_networks = os.getenv('ALLOWED_NETWORKS', '0.0.0.0/0').split(',') if allowed_networks == ['']: allowed_networks = ['0.0.0.0/0'] # See https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-lambda-authorizer.html for payload format def lambda_handler(event, context): sourceIp = event['requestContext']['http']['sourceIp'] print(f'Source IP:{sourceIp}, Allowed Networks:{allowed_networks}') source_address = ipaddress.ip_address(sourceIp) for allowed in allowed_networks: if source_address in ipaddress.ip_network(allowed, False): print('Authorized: Yes') return { "isAuthorized": True } print('Authorized: No') return { "isAuthorized": False } Tags: - Key: StackName Value: !Sub ${AWS::StackName} - Key: StackId Value: !Sub ${AWS::StackId} - Key: GitHub Value: https://github.com/aws-samples/aws-ipranges-api - Key: Description Value: !Sub Authorizer for ${AWS::StackName}-apiGateway lambdaAuthorizerVersion: Type: AWS::Lambda::Version Properties: FunctionName: !Ref lambdaAuthorizerFunction Description: version 1.0 apiGateway: Type: AWS::ApiGatewayV2::Api Properties: Name: !Sub "${AWS::StackName}-api" Description: !Sub "[${AWS::StackName}] - returns AWS IP prefixes from ip-ranges.json" ProtocolType: HTTP DisableExecuteApiEndpoint: !Ref disableDefaultEndPoint Tags: StackName: !Sub ${AWS::StackName} StackId: !Sub ${AWS::StackId} GitHub: "https://github.com/aws-samples/aws-ipranges-api" apiRoute: Type: AWS::ApiGatewayV2::Route Properties: ApiId: !Ref apiGateway RouteKey: "$default" AuthorizationType: CUSTOM AuthorizerId: !Ref apiAuthorizer Target: !Sub "integrations/${apiGatewayIntegration}" apiGatewayIntegration: Type: "AWS::ApiGatewayV2::Integration" Properties: # Uri at https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-custom-integrations.html ApiId: !Ref apiGateway Description: !Sub ${AWS::StackName} Lambda integration with ${apiGateway} IntegrationType: AWS_PROXY IntegrationUri: !Sub "arn:${AWS::Partition}:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${lambdaFunction.Arn}/invocations" IntegrationMethod: POST PayloadFormatVersion: "2.0" TimeoutInMillis: 25000 apiLogGroup: Type: "AWS::Logs::LogGroup" DeletionPolicy: Delete UpdateReplacePolicy: Delete Properties: # Size limit considerations at https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/AWS-logs-and-resource-policy.html#AWS-logs-infrastructure-CWL KmsKeyId: !Ref AWS::NoValue RetentionInDays: !Ref AWS::NoValue LogGroupName: !Sub /${AWS::StackName}/apiLog Tags: - Key: StackName Value: !Sub ${AWS::StackName} - Key: StackId Value: !Sub ${AWS::StackId} - Key: GitHub Value: "https://github.com/aws-samples/aws-ipranges-api" apiLogResourcePolicy: Type: AWS::Logs::ResourcePolicy Properties: PolicyName: !Sub AWSLogDeliveryWrite-${AWS::StackName} PolicyDocument: !Sub '{"Version":"2012-10-17","Statement":[{"Sid":"AWSLogDeliveryWrite","Effect":"Allow","Principal":{"Service":"delivery.logs.amazonaws.com"},"Action":["logs:CreateLogStream","logs:PutLogEvents"],"Resource":"arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:/${AWS::StackName}/apiLog:log-stream:*","Condition":{"StringEquals":{"aws:SourceAccount":"${AWS::AccountId}"},"ArnLike":{"aws:SourceArn":"arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:*"}}}]}' apiStage: Type: "AWS::ApiGatewayV2::Stage" DependsOn: apiLogResourcePolicy Properties: # Account limits at https://docs.aws.amazon.com/apigateway/latest/developerguide/limits.html#apigateway-account-level-limits-table Description: !Sub ${AWS::StackName} API stage for ${apiGateway} StageName: $default AutoDeploy: true ApiId: !Ref apiGateway DefaultRouteSettings: DetailedMetricsEnabled: true #ThrottlingBurstLimit: 50 #ThrottlingRateLimit: 10 AccessLogSettings: # https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html DestinationArn: !GetAtt apiLogGroup.Arn Format: "$context.identity.sourceIp,$context.path,$context.requestTime,$context.httpMethod,$context.routeKey,$context.protocol,$context.status,$context.responseLength,$context.requestId" Tags: StackName: !Sub ${AWS::StackName} StackId: !Sub ${AWS::StackId} GitHub: "https://github.com/aws-samples/aws-ipranges-api" apiAuthorizer: Type: AWS::ApiGatewayV2::Authorizer Properties: ApiId: !Ref apiGateway AuthorizerType: REQUEST AuthorizerPayloadFormatVersion: 2.0 AuthorizerResultTtlInSeconds: 10 IdentitySource: - $context.identity.sourceIp AuthorizerUri: !Sub arn:${AWS::Partition}:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${lambdaAuthorizerFunction.Arn}/invocations EnableSimpleResponses: True Name: !Sub ${AWS::StackName}-authorizer apiTriggerAuthorizerPermission: Type: "AWS::Lambda::Permission" Properties: Action: lambda:InvokeFunction FunctionName: !GetAtt lambdaAuthorizerFunction.Arn Principal: apigateway.amazonaws.com SourceArn: !Sub arn:${AWS::Partition}:execute-api:${AWS::Region}:${AWS::AccountId}:${apiGateway}/* apiTriggerPermission: Type: "AWS::Lambda::Permission" Properties: # See https://docs.aws.amazon.com/lambda/latest/dg/services-apigateway.html#apigateway-permissions Action: lambda:InvokeFunction FunctionName: !GetAtt lambdaFunction.Arn Principal: apigateway.amazonaws.com SourceArn: !Sub "arn:${AWS::Partition}:execute-api:${AWS::Region}:${AWS::AccountId}:${apiGateway}/*" apiCustomDomainName: Condition: useCustomDomainName Type: AWS::ApiGatewayV2::DomainName Properties: DomainName: !Ref customDomainName DomainNameConfigurations: - CertificateArn: !Ref certificateArn EndpointType: REGIONAL SecurityPolicy: TLS_1_2 Tags: StackName: !Sub ${AWS::StackName} StackId: !Sub ${AWS::StackId} GitHub: "https://github.com/aws-samples/aws-ipranges-api" Description: !Sub "Custom domain name for ${apiGateway}" apiMapping: Condition: useCustomDomainName DependsOn: - apiCustomDomainName - apiStage Type: AWS::ApiGatewayV2::ApiMapping Properties: DomainName: !Ref customDomainName ApiId: !Ref apiGateway Stage: $default Outputs: apiInvokeURL: Condition: useCustomDomainName Description: "Custom domain name for use by firewall or application. Create DNS record first" Value: !Sub "https://${customDomainName}" apiFQDN: Condition: useCustomDomainName Description: "Create your customDomainName DNS record to this FQDN" Value: !GetAtt apiCustomDomainName.RegionalDomainName apiGatewayInvokeURL: Condition: enableDefaultEndPoint Description: URL for use by firewall or application Value: !GetAtt apiGateway.ApiEndpoint apiGatewayLog: Description: Cloudwatch log for API Gateway Value: !Sub https://console.aws.amazon.com/cloudwatch/home?region=${AWS::Region}#logsV2:log-groups/log-group/$252F${AWS::StackName}$252FapiLog lambdaFunctionLog: Description: Cloudwatch log for Lambda function Value: !Sub https://console.aws.amazon.com/cloudwatch/home?region=${AWS::Region}#logsV2:log-groups/log-group/$252Faws$252Flambda$252F${lambdaFunctionName} lambdaAuthorizerFunctionLog: Description: Cloudwatch log for Lambda authorizer function Value: !Sub https://console.aws.amazon.com/cloudwatch/home?region=${AWS::Region}#logsV2:log-groups/log-group/$252Faws$252Flambda$252F${lambdaAuthorizerFunctionName}