¿Cómo actualizo el módulo cfn-response de AWS CloudFormation para las funciones de Lambda de AWS que se ejecutan en Python 2.7/3.6/3.7?
Quiero actualizar el módulo cfn-response de AWS CloudFormation para las funciones de AWS Lambda que se ejecutan en Python 2.7/3.6/3.7.
Resolución
Nota: Los siguientes pasos son pertinentes solo para las funciones de Lambda que se ejecutan en Python 2.7/3.6/3.7. Los siguientes comandos son válidos para entornos Linux y macOS. La sintaxis puede variar en Windows PowerShell.
Nota: Si recibe errores al ejecutar los comandos de la interfaz de la línea de comandos de AWS (AWS CLI), asegúrese de usar la versión más reciente de AWS CLI.
1. Para encontrar las pilas que contienen recursos personalizados, ejecute el siguiente comando:
aws cloudformation list-stacks --region us-east-1 | grep -oE 'arn:[^"]+' | while read arn; do aws cloudformation list-stack-resources --stack-name $arn --region us-east-1 | grep -E '(Custom::)|(::CustomResource)' | awk '{print $2}' | while read resource; do if [[ -n $resource ]]; then echo $arn; echo $resource; fi; done; done
Debería ver un resultado similar al del siguiente ejemplo:
arn:aws:cloudformation:us-east-1:123456789012:stack/TestStack/3497b950-55f1-11eb-aad4-124a026c8667 "ResourceType": "AWS::CloudFormation::CustomResource",
2. Para encontrar la función de Lambda asociada al recurso personalizado, ejecute el siguiente comando para comprobar la propiedad ServiceToken del recurso personalizado desde la plantilla de la pila:
aws cloudformation get-template --stack-name TestStack | jq -r .TemplateBody
Nota: El comando del paso 2 muestra una vista previa de la plantilla de la pila utilizando la opción jq (de la página web de jq) para dar formato a la respuesta.
Debería ver un resultado similar al del siguiente ejemplo:
Resources: MyCustomResource: Type: AWS::CloudFormation::CustomResource Properties: ServiceToken: !GetAtt MyFunction.Arn Name: "John" MyFunction: Type: AWS::Lambda::Function Properties: Handler: index.handler Role: !GetAtt MyRole.Arn Runtime: python3.7 Code: ZipFile: | import cfnresponse def handler(event, context): responseData = {'Message': 'Hello {}!'.format(event['ResourceProperties']['Name'])} cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData, "CustomResourcePhysicalID") MyRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - sts:AssumeRole ManagedPolicyArns: - "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" Outputs: Result: Value: !GetAtt MyCustomResource.Message
Nota: La plantilla que se obtiene del resultado del paso 2 es un ejemplo de plantilla básica para un recurso personalizado basado en Lambda. La propiedad ServiceToken: !GetAtt MyFunction.Arn se encuentra en la sección MyCustomResource. El valor obtenido por el método !GetAtt MyFunction**.Arn** de la propiedad ServiceToken es el nombre de recurso de Amazon (ARN) del tema de Amazon Simple Notification Service (Amazon SNS) o de la función de Lambda.
3. En la plantilla del paso 2, identifique dónde está definida su función de Lambda.
Si su función de Lambda se encuentra en la misma pila que el recurso personalizado, vaya al paso 4. Por ejemplo, la función Fn::GetAtt del paso 2 muestra que la función de Lambda está definida en la misma plantilla que el recurso personalizado.
Si la propiedad ServiceToken dirige a un ARN con código rígido, la función de Lambda podría estar en otra pila. Si la propiedad ServiceToken se resuelve a través de Fn::Import, utilice la API list-exports de AWS CloudFormation para buscar el valor. Por ejemplo:
aws cloudformation list-exports --region us-east-1 { "Exports": [ { "ExportingStackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/SomeOtherStack/481dc040-b283-11e9-b1bd-12d607a4fd1c", "Value": "arn:aws:lambda:us-east-1:123456789012:function:SomeOtherStack-MyFunction-5ZE2CQO8RAA9", "Name": "MyExport" } ] }
A continuación, compruebe si hay etiquetas de función ubicadas en una pila independiente utilizando list-tags para localizar el ARN de la pila de AWS CloudFormation. Por ejemplo:
aws lambda list-tags --resource arn:aws:lambda:us-east-1:123456789012:function:TestStack-MyFunction-5ZE2CQO8RAA9 | grep stack-id
Recibirá un resultado similar al siguiente:
"aws:cloudformation:stack-id": "arn:aws:cloudformation:us-east-1:123456789012:stack/TestStack/3497b950-55f1-11eb-aad4-124a026c8667"
Nota: También puede encontrar etiquetas de función en la consola de AWS Lambda.
4. Para permitir que AWS CloudFormation cargue el módulo cfn-response más reciente en su función de Lambda, actualice el código fuente integrado de su función de Lambda. Por ejemplo:
Code: ZipFile: | import cfnresponse def handler(event, context): responseData = {'Message': 'Hello {}!'.format(event['ResourceProperties']['Name'])} cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData, "CustomResourcePhysicalID")
Nota: Consulte el paso 2 para ver una plantilla de ejemplo que tiene una función de Lambda con código fuente integrado.
Ahora, AWS CloudFormation carga el siguiente ejemplo de código del módulo cfn-response en su función de Lambda. Por ejemplo:
from botocore.vendored import requests import json SUCCESS = "SUCCESS" FAILED = "FAILED" def send(event, context, responseStatus, responseData, physicalResourceId=None, noEcho=False): responseUrl = event['ResponseURL'] print(responseUrl) responseBody = {} responseBody['Status'] = responseStatus responseBody['Reason'] = 'See the details in CloudWatch Log Stream: ' + context.log_stream_name responseBody['PhysicalResourceId'] = physicalResourceId or context.log_stream_name responseBody['StackId'] = event['StackId'] responseBody['RequestId'] = event['RequestId'] responseBody['LogicalResourceId'] = event['LogicalResourceId'] responseBody['NoEcho'] = noEcho responseBody['Data'] = responseData
Nota: Para obtener más información, consulte los ejemplos de código en la sección «Código fuente del módulo» del módulo cfn-response.
El ejemplo de código del módulo cfn-response utiliza botocore.requests en el paquete de despliegue de la función de Lambda.
Para actualizar el módulo cfn-response a la última versión que utiliza urllib3, actualice el código integrado de la función en la plantilla de AWS CloudFormation. Para ello, añada un comentario al código integrado de la función de Lambda. Por ejemplo:
ZipFile: | import cfnresponse def handler(event, context): + # This comment was added to force an update on this function's code responseData = {'Message': 'Hello {}!'.format(event['ResourceProperties']['Name'])} cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData, "CustomResourcePhysicalID") MyRole:
5. Guarde los cambios realizados en la plantilla que contiene su función de Lambda.
El módulo cfn-response se modifica una vez que la pila ha terminado de actualizarse.
Nota: Si el código de su función está ubicado en un bucket de Amazon Simple Storage Service (Amazon S3) o en una imagen de Amazon Elastic Container Registry (Amazon ECR), deberá actualizar el módulo usted mismo para incluir la versión con urllib3. Para obtener el código fuente de la última versión del módulo cfn-response, consulte cfn-response module.
Nota: Si un tiempo de ejecución nuevo de Python o JavaScript introduce un cambio disruptivo, debe actualizar el módulo cfn-response. En lugar de actualizar de nuevo el archivo zip, puede adjuntar automáticamente la versión más reciente del módulo cfn-response cada vez que se actualice la propiedad Runtime de una función.
Contenido relevante
- OFICIAL DE AWSActualizada hace 2 meses
- OFICIAL DE AWSActualizada hace 24 días
- OFICIAL DE AWSActualizada hace un año
- OFICIAL DE AWSActualizada hace 2 años