New user sign up using AWS Builder ID
New user sign up using AWS Builder ID is currently unavailable on re:Post. To sign up, please use the AWS Management Console instead.
Wie behebe ich die zirkuläre Abhängigkeit zwischen einer AWS Lambda-Berechtigung und Zielgruppenressourcen in AWS CloudFormation?
Ich möchte die zirkuläre Abhängigkeit zwischen einer AWS Lambda-Berechtigung (AWS: :Lambda: :Permission) und Zielgruppenressourcen (AWS: :ElasticLoadBalancingV2: :TargetGroup) in AWS CloudFormation beheben.
Kurzbeschreibung
Sie erhalten eine zirkuläre Abhängigkeit, wenn Sie AWS::Lambda::Permission für AWS::ElasticLoadBalancingV2::TargetGroup anstelle von LoadBalancer bereitstellen, um den Zugriff auf Ihre Lambda-Funktion einzuschränken. Dies liegt daran, dass die Lambda-Berechtigung vorhanden sein muss, bevor Sie die Lambda-Funktion der Zielgruppe zuordnen, die Sie erstellen möchten. Wenn Sie die Lambda-Berechtigung erstellen, müssen Sie die Berechtigung einem AWS-Principal und sourceARN (in diesem Fall einer Zielgruppe) zuordnen. Deshalb muss die Zielgruppe existieren, bevor die Lambda-Berechtigung erstellt wird. Um diese zirkuläre Abhängigkeit zu beheben, können Sie eine von Lambda unterstützte benutzerdefinierte Ressource verwenden.
Behebung
1. Erstellen Sie eine Datei mit dem Namen index.py, die Folgendes enthält:
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 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. def handler(event, context): return { "statusCode": 200, "statusDescription": "HTTP OK", "isBase64Encoded": False, "headers": { "Content-Type": "text/html" }, "body": "<h1>Hello from Lambda!</h1>" }
Hinweis: Die AWS Lambda-Funktion in index.py zeigt eine HTML-Seite mit der Meldung „Hallo von Lambda! „wenn die Funktion aufgerufen wird.
2. Fügen Sie die Datei index.py zu einer Archivdatei mit dem Namen website.zip hinzu.
3. Führen Sie den folgenden Befehl aus, um eine ZIP-Datei von index.py zu erstellen:
$zip website.zip index.py
4. Erstellen Sie eine Datei mit dem Namen cfnresponse.py, die auf der AWS CloudFormation-Vorlage auf AWS GitHub basiert.
5. Erstellen Sie eine Füllung mit dem Namen custom.py, die auf den folgenden Elementen basiert:
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 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. import logging import boto3, json, botocore import cfnresponse #Define logging properties for 'logging' log = logging.getLogger() log.setLevel(logging.INFO) #Main Lambda function to be executed def lambda_handler(event, context): try: if event['RequestType'] == "Create" or event['RequestType'] == "Update": # print the event type sent from cloudformation log.info ("'" + str(event['RequestType']) + "' event was sent from CFN") # Imput Parameters TargetGroupARN = event['ResourceProperties']['TargetGroupARN'] LambdaFunctionARN = event['ResourceProperties']['LambdaFunctionARN'] log.info("TargetGroup ARN value is:" + TargetGroupARN) log.info("Lambda Function ARN value is:" + LambdaFunctionARN) responseData = {} # ELBV2 initilize client = boto3.client('elbv2') # Initilize Vars response = '' error_msg = '' # Make the 1st API call to get the Lambda policy and extract SID of the initial permissions that were created by the CFN template. try: response = client.register_targets( TargetGroupArn=TargetGroupARN, Targets=[ { 'Id': LambdaFunctionARN }, ] ) except botocore.exceptions.ClientError as e: error_msg = str(e) if error_msg: log.info("Error Occured:" + error_msg) response_msg = error_msg # TODO: SIGNAL BACK TO CLOUDFORMATION log.info("Trying to signal FAILURE back to cloudformation.") responseData = {"Message" : response_msg, "Function" : context.log_stream_name} cfnresponse.send(event, context, cfnresponse.FAILED, responseData) else: response_msg = "Successfully Added Lambda(" + LambdaFunctionARN + ") as Target" log.info(response_msg) # TODO: SIGNAL BACK TO CLOUDFORMATION log.info("Trying to signal SUCCESS back to cloudformation.") responseData = {"Message" : response_msg, "Function" : context.log_stream_name} cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData) # log the end of the create event log.info ("End of '" + str(event['RequestType']) + "' Event") elif "Delete" in str(event['RequestType']): # print the event type sent from cloudformation log.info ("'Delete' event was sent from CFN") # TODO: DELETE THINGS log.info("TODO: DELETE THINGS") # TODO: SIGNAL BACK TO CLOUDFORMATION log.info("Trying to signal SUCCESS back to cloudformation.") responseData = {"Function" : context.log_stream_name} cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData) # log the end of the Delete event log.info ("End of 'Delete' Event") else: log.info ("RequestType sent from cloudformation is invalid.") log.info ("Was expecting 'Create', 'Update' or 'Delete' RequestType(s).") log.info ("The detected RequestType is : '" + str(event['RequestType']) + "'") #TODO: SIGNAL BACK TO CLOUDFORMATION log.info("Trying to signal FAILURE back to cloudformation due to invalid request type.") responseData={"Function" : context.log_stream_name} cfnresponse.send(event, context, cfnresponse.FAILED, responseData) except Exception as e: log.info ("Function failed due to the following error:") print (e) #TODO: SIGNAL BACK TO CLOUDFORMATION log.info("Trying to signal FAILURE back to cloudformation due to the error.") responseData={"Function" : context.log_stream_name} cfnresponse.send(event, context, cfnresponse.FAILED, responseData)
Hinweis: Die Lambda-Funktion in custom.py führt den RegisterTargets-API-Aufruf aus und signalisiert AWS CloudFormation nach Abschluss dieses API-Aufrufs.
6. Fügen Sie die Dateien cfnresponse.py und custom.py zu einer Archivdatei mit dem Namen custom.zip hinzu. Zum Beispiel:
zip custom.zip cfnresponse.py custom.py
Hinweis: Die Datei custom.py verwendet den Boto3-API-Aufruf registerTargets. Dieser API-Aufruf registriert die angegebenen Ziele bei der angegebenen Zielgruppe. Weitere Informationen finden Sie im Python-Snippet register_targets von der Boto3-Website. Die Datei cfnresponse.py enthält eine Funktion, die Protokolle und Benachrichtigungen an Amazon CloudWatch und AWS CloudFormation weiterleitet.
7. Erstellen Sie eine AWS CloudFormation-Vorlage mithilfe der folgenden YAML-Vorlage:
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 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. AWSTemplateFormatVersion: 2010-09-09 Description: HelloWorld Lambda function template for Application Load Balancer Lambda as target Parameters: # VPC in which the LoadBalancer and the LoadBalancer SecurityGroup will be created VpcId: Type: AWS::EC2::VPC::Id # Subnets in which the LoadBalancer will be created. Subnets: Type: List<AWS::EC2::Subnet::Id> # Name of the TargetGroup TargetGroupName: Type: String Default: 'MyTargets' # Name of the S3 bucket where custom.zip and website.zip are uploaded to S3BucketName: Type: String Default: you-s3-bucket-name Resources: LambdaExecutionRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - sts:AssumeRole Path: "/" Policies: - PolicyName: root PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - '*' Resource: '*' # Lambda function which displays an HTML page with "Hello from Lambda!" message upon invocation HelloWorldFunction1234: Type: 'AWS::Lambda::Function' Properties: Code: S3Bucket: !Ref S3BucketName S3Key: website.zip FunctionName: testLambda MemorySize: 128 Handler: index.handler Timeout: 30 Runtime: python3.7 Role: !GetAtt LambdaExecutionRole.Arn LoadBalancer: Type: AWS::ElasticLoadBalancingV2::LoadBalancer Properties: Scheme: internet-facing Subnets: !Ref Subnets SecurityGroups: - !Ref LoadBalancerSecurityGroup HttpListener: Type: 'AWS::ElasticLoadBalancingV2::Listener' Properties: DefaultActions: - TargetGroupArn: !Ref TargetGroup Type: forward LoadBalancerArn: !Ref LoadBalancer Port: 80 Protocol: HTTP LoadBalancerSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Allow http to client host VpcId: !Ref VpcId SecurityGroupIngress: - IpProtocol: tcp FromPort: 80 ToPort: 80 CidrIp: 0.0.0.0/0 HelloWorldFunctionInvokePermission: Type: AWS::Lambda::Permission Properties: FunctionName: !GetAtt HelloWorldFunction1234.Arn Action: 'lambda:InvokeFunction' Principal: elasticloadbalancing.amazonaws.com SourceArn: !Sub - >- arn:aws:elasticloadbalancing:${AWS::Region}:${AWS::AccountId}:${TGFullName} - TGFullName: !GetAtt TargetGroup.TargetGroupFullName TargetGroup: Type: AWS::ElasticLoadBalancingV2::TargetGroup Properties: Name: !Ref TargetGroupName TargetType: lambda # Custom resource for Lambda function - "HelloWorldFunction1234" HelloWorld: DependsOn: [TargetGroup, HelloWorldFunctionInvokePermission] Type: Custom::HelloWorld Properties: ServiceToken: !GetAtt TestFunction.Arn # Input parameters for the Lambda function LambdaFunctionARN: !GetAtt HelloWorldFunction1234.Arn TargetGroupARN: !Sub - >- arn:aws:elasticloadbalancing:${AWS::Region}:${AWS::AccountId}:${TGFullName} - TGFullName: !GetAtt TargetGroup.TargetGroupFullName # Lambda function that performs RegisterTargets API call TestFunction: Type: AWS::Lambda::Function Properties: Code: S3Bucket: !Ref S3BucketName S3Key: custom.zip Handler: custom.lambda_handler Role: !GetAtt LambdaExecutionRole.Arn Runtime: python3.7 Timeout: '5' Outputs: Message: Description: Message returned from Lambda Value: !GetAtt - HelloWorld - Message
8. Übergeben Sie Ihre Werte für die S3BucketName, Subnets, VpcId, und TargetGroupName an den AWS CloudFormation-Stack, den Sie mithilfe der Vorlage in Schritt 7 erstellt haben.
10. Nachdem alle API-Aufrufe abgeschlossen sind, wechseln Sie zum Abschnitt Outputs der AWS CloudFormation -Konsole und suchen Sie dann nach der folgenden Meldung:
Successfully Added Lambda(arn:aws:lambda:us-east-1:123456789:function:testLambda) as Target

Relevanter Inhalt
- AWS OFFICIALAktualisiert vor 3 Jahren
- AWS OFFICIALAktualisiert vor 4 Jahren