Crie funções Lambda para avaliar recursos para Lambda Hooks - AWS CloudFormation

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

Crie funções Lambda para avaliar recursos para Lambda Hooks

AWS CloudFormation O Lambda Hooks permite que você CloudFormation avalie e AWS Cloud Control API opere com base em seu próprio código personalizado. Seu Hook pode impedir que uma operação continue, ou emitir um aviso para o chamador e permitir que a operação continue. Ao criar um Lambda Hook, você pode configurá-lo para interceptar e avaliar as seguintes operações: CloudFormation

  • Operações de recurso

  • Operações de empilhamento

  • Alterar as operações do conjunto

Desenvolvendo um Lambda Hook

Quando Hooks invocam seu Lambda, ele espera até 30 segundos para que o Lambda avalie a entrada. O Lambda retornará uma JSON resposta que indica se o Hook foi bem-sucedido ou falhou.

Solicitar entrada

A entrada passada para sua função Lambda depende da operação de destino do Hook (exemplos: pilha, recurso ou conjunto de alterações).

Entrada de resposta

Para se comunicar com Hooks se sua solicitação foi bem-sucedida ou falhou, sua função Lambda precisa retornar uma resposta. JSON

A seguir está um exemplo da forma da resposta que Hooks espera:

{ "hookStatus": "SUCCESS" or "FAILED" or "IN_PROGRESS", "errorCode": None or "NonCompliant" or "InternalFailure" "message": String, "clientRequestToken": String "callbackContext": None, "callbackDelaySeconds": Integer, }
hookStatus

O status do Hook. Este é um campo obrigatório.

Valores válidos: (SUCCESS| FAILED |IN_PROGRESS)

nota

Um gancho pode retornar IN_PROGRESS 3 vezes. Se nenhum resultado for retornado, o Hook falhará. Para um Lambda Hook, isso significa que sua função Lambda pode ser invocada até 3 vezes.

errorCode

Mostra se a operação foi avaliada e determinada como inválida ou se ocorreram erros no Hook, impedindo a avaliação. Esse campo é obrigatório se o Hook falhar.

Valores válidos: (NonCompliant|InternalFailure)

message

A mensagem para o chamador informando por que o Hook foi bem-sucedido ou falhou.

nota

Ao avaliar CloudFormation as operações, esse campo é truncado para 4096 caracteres.

Ao avaliar as API operações do Cloud Control, esse campo é truncado para 1024 caracteres.

clientRequestToken

O token de solicitação que foi fornecido como entrada para a solicitação do Hook. Este é um campo obrigatório.

callbackContext

Se você indicar que hookStatus é, IN_PROGRESS você passa um contexto adicional que é fornecido como entrada quando a função Lambda é invocada novamente.

callbackDelaySeconds

Quanto tempo os Hooks devem esperar para invocar esse Hook novamente.

Exemplos

Veja a seguir um exemplo de uma resposta bem-sucedida:

{ "hookStatus": "SUCCESS", "message": "compliant", "clientRequestToken": "123avjdjk31" }

Veja a seguir um exemplo de falha na resposta:

{ "hookStatus": "FAILED", "errorCode": "NON_COMPLIANT", "message": "S3 Bucket Versioning must be enabled.", "clientRequestToken": "123avjdjk31" }

Avaliando as operações de recursos com Lambda Hooks

Sempre que você cria, atualiza ou exclui um recurso, isso é considerado uma operação de recurso. Por exemplo, se você executar a atualização de uma CloudFormation pilha que cria um novo recurso, você concluiu uma operação de recurso. Quando você cria, atualiza ou exclui um recurso usando o Cloud ControlAPI, isso também é considerado uma operação de recurso. Você pode configurar seu CloudFormation Lambda Hook para destinos RESOURCE e CLOUD_CONTROL operações na configuração do HookTargetOperations.

nota

O manipulador delete Hook só é invocado quando um recurso é excluído usando um gatilho de operação de cloud-control delete-resource ou. cloudformation delete-stack

Sintaxe de entrada de recursos do Lambda Hook

Quando seu Lambda for invocado para uma operação de recurso, você receberá uma JSON entrada contendo as propriedades do recurso, as propriedades propostas e o contexto em torno da invocação do Hook.

Veja a seguir um exemplo de formato da JSON entrada:

{ "awsAccountId": String, "stackId": String, "changeSetId": String, "hookTypeName": String, "hookTypeVersion": String, "hookModel": { "LambdaFunction": String }, "actionInvocationPoint": "CREATE_PRE_PROVISION" or "UPDATE_PRE_PROVISION" or "DELETE_PRE_PROVISION" "requestData": { "targetName": String, "targetType": String, "targetLogicalId": String, "targetModel": { "resourceProperties": {...}, "previousResourceProperties": {...} } }, "requestContext": { "invocação": 1, "callbackContext": null } }
awsAccountId

O ID do Conta da AWS que contém o recurso que está sendo avaliado.

stackId

O ID da pilha da CloudFormation qual essa operação faz parte. Esse campo estará vazio se o chamador for o Cloud ControlAPI.

changeSetId

O ID do conjunto de alterações que iniciou a invocação do Hook. Esse valor ficará vazio se a alteração do recurso tiver sido iniciada pelo Cloud Control API ou pelas delete-stack operações create-stackupdate-stack, ou.

hookTypeName

O nome do Hook que está funcionando.

hookTypeVersion

A versão do Hook que está sendo executada.

hookModel
LambdaFunction

A Lambda atual ARN invocada pelo Hook.

actionInvocationPoint

O ponto exato na lógica de provisionamento em que o Hook é executado.

Valores válidos: (CREATE_PRE_PROVISION| UPDATE_PRE_PROVISION |DELETE_PRE_PROVISION)

requestData
targetName

O nome do recurso de destino que está sendo criado.

targetType

O tipo de alvo que está sendo criado, por exemploAWS::S3::Bucket.

targetLogicalId

O ID lógico do recurso que está sendo avaliado. Se a origem da invocação do Hook for CloudFormation, esse será o ID lógico do recurso definido em seu CloudFormation modelo. Se a origem dessa invocação de Hook for Cloud ControlAPI, esse será um valor construído.

targetModel
resourceProperties

As propriedades propostas do recurso que está sendo modificado. Se o recurso estiver sendo excluído, esse valor ficará vazio.

previousResourceProperties

As propriedades atualmente associadas ao recurso que está sendo modificado. Se o recurso estiver sendo criado, esse valor ficará vazio.

requestContext
invocação

A tentativa atual de executar o Hook.

callbackContext

Se o Hook foi configurado para IN_PROGRESS e callbackContext foi devolvido, ele estará aqui após a reinvocação.

Exemplo de entrada de alteração de recursos do Lambda Hook

No exemplo de entrada a seguir, o Guard Hook receberá a definição do AWS::DynamoDB::Table recurso que está sendo alterado. Os ReadCapacityUnits parâmetros ProvisionedThroughput e estão sendo atualizados de 3 para 10.

Para obter mais informações sobre as propriedades disponíveis para o recurso, consulte AWS: :DynamoDB: :Table.

{ "awsAccountId": "123456789", "stackId": "arn:aws:cloudformation:eu-central-1:123456789:stack/test-stack/123456abcd", "hookTypeName": "my::lambda::resourcehookfunction", "hookTypeVersion": "00000008", "hookModel": { "LambdaFunction": "arn:aws:lambda:eu-central-1:123456789:function:resourcehookfunction" }, "actionInvocationPoint": "UPDATE_PRE_PROVISION", "requestData": { "targetName": "AWS::DynamoDB::Table", "targetType": "AWS::DynamoDB::Table", "targetLogicalId": "DDBTable", "targetModel": { "resourceProperties": { "AttributeDefinitions": [ { "AttributeType": "S", "AttributeName": "Album" }, { "AttributeType": "S", "AttributeName": "Artist" } ], "ProvisionedThroughput": { "WriteCapacityUnits": 5, "ReadCapacityUnits": 10 }, "KeySchema": [ { "KeyType": "HASH", "AttributeName": "Album" }, { "KeyType": "RANGE", "AttributeName": "Artist" } ] }, "previousResourceProperties": { "AttributeDefinitions": [ { "AttributeType": "S", "AttributeName": "Album" }, { "AttributeType": "S", "AttributeName": "Artist" } ], "ProvisionedThroughput": { "WriteCapacityUnits": 5, "ReadCapacityUnits": 5 }, "KeySchema": [ { "KeyType": "HASH", "AttributeName": "Album" }, { "KeyType": "RANGE", "AttributeName": "Artist" } ] } } }, "requestContext": { "invocation": 1, "callbackContext": null } }

Exemplo de função Lambda para operações de recursos

O exemplo a seguir é um alvo do Lambda Hook. Node.js Essa é uma função simples que falha em qualquer atualização de recurso para o DynamoDB, que tenta definir ProvisionedThroughput ReadCapacity o como algo maior que 10. Se o Hook for bem-sucedido, a mensagem “ReadCapacity está configurado corretamente” será exibida para o chamador. Se a solicitação falhar na validação, o Hook falhará com o status “ReadCapacity não pode ser maior que 10”.

export const handler = async (event, context) => { var targetModel = event?.requestData?.targetModel; var targetName = event?.requestData?.targetName; var response = { "hookStatus": "SUCCESS", "message": "ReadCapacity is correctly configured.", "clientRequestToken": event.clientRequestToken }; if (targetName == "AWS::DynamoDB::Table") { var readCapacity = targetModel?.resourceProperties?.ProvisionedThroughput?.ReadCapacityUnits; if (readCapacity > 10) { response.hookStatus = "FAILED"; response.errorCode = "NonCompliant"; response.message = "ReadCapacity must be cannot be more than 10."; } } return response; };

Avaliação de operações de pilha com Lambda Hooks

Sempre que você cria, atualiza ou exclui uma pilha com um novo modelo, você pode configurar seu CloudFormation Lambda Hook para começar avaliando o novo modelo e potencialmente impedir que a operação da pilha continue. Você pode configurar seu CloudFormation Lambda Hook para direcionar STACK operações na configuração do HookTargetOperations.

Sintaxe de entrada da pilha Lambda Hook

Quando seu Lambda for invocado para uma operação de pilha, você receberá uma JSON solicitação contendo o contexto de invocação do Hook e o contexto da solicitação. actionInvocationPoint Devido ao tamanho dos CloudFormation modelos e ao tamanho limitado de entrada aceito pelas funções do Lambda, os modelos reais são armazenados em um objeto Amazon S3. A entrada do requestData inclui um Amazon S3 resignado URL a outro objeto, que contém a versão atual e anterior do modelo.

Veja a seguir um exemplo de formato da JSON entrada:

{ "clientRequesttoken": String, "awsAccountId": String, "stackID": String, "changeSetId": String, "hookTypeName": String, "hookTypeVersion": String, "hookModel": { "LambdaFunction":String }, "actionInvocationPoint": "CREATE_PRE_PROVISION" or "UPDATE_PRE_PROVISION" or "DELETE_PRE_PROVISION" "requestData": { "targetName": "STACK", "targetType": "STACK", "targetLogicalId": String, "payload": String (S3 Presigned URL) }, "requestContext": { "invocation": Integer, "callbackContext": String } }
clientRequesttoken

O token de solicitação que foi fornecido como entrada para a solicitação do Hook. Este é um campo obrigatório.

awsAccountId

O ID do Conta da AWS que contém a pilha que está sendo avaliada.

stackID

O ID da pilha. CloudFormation

changeSetId

O ID do conjunto de alterações que iniciou a invocação do Hook. Esse valor estará vazio se a alteração da pilha tiver sido iniciada pelas delete-stack operações Cloud Control ou APIcreate-stack,update-stack, ou.

hookTypeName

O nome do Hook que está funcionando.

hookTypeVersion

A versão do Hook que está sendo executada.

hookModel
LambdaFunction

A Lambda atual ARN invocada pelo Hook.

actionInvocationPoint

O ponto exato na lógica de provisionamento em que o Hook é executado.

Valores válidos: (CREATE_PRE_PROVISION| UPDATE_PRE_PROVISION |DELETE_PRE_PROVISION)

requestData
targetName

Esse valor será STACK.

targetType

Esse valor será STACK.

targetLogicalId

O nome da pilha.

payload

O Amazon S3 pré-assinado URL contendo um JSON objeto com as definições de modelo atuais e anteriores.

requestContext

Se o Hook estiver sendo invocado novamente, esse objeto será definido.

invocation

A tentativa atual de executar o Hook.

callbackContext

Se o Hook foi configurado IN_PROGRESS e callbackContext foi devolvido, ele estará aqui após a reinvocação.

A payload propriedade nos dados da solicitação é URL aquela que seu código precisa buscar. Depois de receber oURL, você obtém um objeto com o seguinte esquema:

{ "template": String, "previousTemplate": String }
template

O CloudFormation modelo completo que foi fornecido para create-stack ouupdate-stack. Ela pode ser uma YAML string JSON ou, dependendo do que foi fornecido CloudFormation.

Nas delete-stack operações, esse valor estará vazio.

previousTemplate

O CloudFormation modelo anterior. Ela pode ser uma YAML string JSON ou, dependendo do que foi fornecido CloudFormation.

Nas delete-stack operações, esse valor estará vazio.

Exemplo de entrada de alteração de pilha do Lambda Hook

Veja a seguir um exemplo de entrada de alteração de pilha. O Hook está avaliando uma alteração que atualiza o ObjectLockEnabled para true e adiciona uma SQS fila da Amazon:

{ "clientRequestToken": "f8da6d11-b23f-48f4-814c-0fb6a667f50e", "awsAccountId": "123456789", "stackId": "arn:aws:cloudformation:eu-central-1:123456789:stack/david-ddb-test-stack/400b40f0-8e72-11ef-80ab-02f2902f0df1", "changeSetId": null, "hookTypeName": "my::lambda::stackhook", "hookTypeVersion": "00000008", "hookModel": { "LambdaFunction": "arn:aws:lambda:eu-central-1:123456789:function:stackhookfunction" }, "actionInvocationPoint": "UPDATE_PRE_PROVISION", "requestData": { "targetName": "STACK", "targetType": "STACK", "targetLogicalId": "my-cloudformation-stack", "payload": "https://s3......" }, "requestContext": { "invocation": 1, "callbackContext": null } }

Este é um exemplo payload dorequestData:

{ "template": "{\"Resources\":{\"S3Bucket\":{\"Type\":\"AWS::S3::Bucket\",\"Properties\":{\"ObjectLockEnabled\":true}},\"SQSQueue\":{\"Type\":\"AWS::SQS::Queue\",\"Properties\":{\"QueueName\":\"NewQueue\"}}}}", "previousTemplate": "{\"Resources\":{\"S3Bucket\":{\"Type\":\"AWS::S3::Bucket\",\"Properties\":{\"ObjectLockEnabled\":false}}}}" }

Exemplo de função Lambda para operações de pilha

O exemplo a seguir é a segmentação do Lambda Hook. Node.js É uma função simples que baixa a carga útil da operação de pilha, analisa o modelo JSON e retorna. SUCCESS

export const handler = async (event, context) => { var targetType = event?.requestData?.targetType; var payloadUrl = event?.requestData?.payload; var response = { "hookStatus": "SUCCESS", "message": "Stack update is compliant", "clientRequestToken": event.clientRequestToken }; try { const templateHookPayloadRequest = await fetch(payloadUrl); const templateHookPayload = await templateHookPayloadRequest.json() if (templateHookPayload.template) { // Do something with the template templateHookPayload.template // JSON or YAML } if (templateHookPayload.previousTemplate) { // Do something with the template templateHookPayload.previousTemplate // JSON or YAML } } catch (error) { console.log(error); response.hookStatus = "FAILED"; response.message = "Failed to evaluate stack operation."; response.errorCode = "InternalFailure"; } return response; };

Avaliando as operações do conjunto de alterações com Lambda Hooks

Sempre que criar um conjunto de alterações, você pode configurar seu CloudFormation Lambda Hook para avaliar primeiro o novo conjunto de alterações e potencialmente bloquear sua execução. Você pode configurar seu CloudFormation Lambda Hook para direcionar CHANGE_SET operações na configuração do HookTargetOperations.

Sintaxe de entrada do conjunto de alterações do Lambda Hook

A entrada para as operações do conjunto de alterações é semelhante às operações de pilha, mas a carga útil do requestData também inclui uma lista de alterações de recursos introduzidas pelo conjunto de alterações.

Veja a seguir um exemplo de formato da JSON entrada:

{ "clientRequesttoken": String, "awsAccountId": String, "stackID": String, "changeSetId": String, "hookTypeName": String, "hookTypeVersion": String, "hookModel": { "LambdaFunction":String }, "requestData": { "targetName": "CHANGE_SET", "targetType": "CHANGE_SET", "targetLogicalId": String, "payload": String (S3 Presigned URL) }, "requestContext": { "invocation": Integer, "callbackContext": String } }
clientRequesttoken

O token de solicitação que foi fornecido como entrada para a solicitação do Hook. Este é um campo obrigatório.

awsAccountId

O ID do Conta da AWS que contém a pilha que está sendo avaliada.

stackID

O ID da pilha. CloudFormation

changeSetId

O ID do conjunto de alterações que iniciou a invocação do Hook.

hookTypeName

O nome do Hook que está funcionando.

hookTypeVersion

A versão do Hook que está sendo executada.

hookModel
LambdaFunction

A Lambda atual ARN invocada pelo Hook.

requestData
targetName

Esse valor será CHANGE_SET.

targetType

Esse valor será CHANGE_SET.

targetLogicalId

O conjunto de mudançasARN...

payload

O Amazon S3 pré-assinado URL contendo um JSON objeto com o modelo atual, bem como uma lista de alterações introduzidas por esse conjunto de alterações.

requestContext

Se o Hook estiver sendo invocado novamente, esse objeto será definido.

invocation

A tentativa atual de executar o Hook.

callbackContext

Se o Hook foi configurado IN_PROGRESS e callbackContext foi devolvido, ele estará aqui após a reinvocação.

A payload propriedade nos dados da solicitação é URL aquela que seu código precisa buscar. Depois de receber oURL, você obtém um objeto com o seguinte esquema:

{ "template": String, "changedResources": [ { "action": String, "beforeContext": JSON String, "afterContext": JSON String, "lineNumber": Integer, "logicalResourceId": String, "resourceType": String } ] }
template

O CloudFormation modelo completo que foi fornecido para create-stack ouupdate-stack. Ela pode ser uma YAML string JSON ou, dependendo do que foi fornecido CloudFormation.

changedResources

Uma lista dos recursos alterados.

action

O tipo de alteração aplicada ao recurso.

Valores válidos: (CREATE| UPDATE |DELETE)

beforeContext

Uma JSON sequência das propriedades do recurso antes da alteração. Esse valor é nulo quando o recurso está sendo criado. Todos os valores booleanos e numéricos nessa JSON string sãoSTRINGS.

afterContext

Uma JSON string das propriedades dos recursos se esse conjunto de alterações for executado. Esse valor é nulo quando o recurso está sendo excluído. Todos os valores booleanos e numéricos nessa JSON string sãoSTRINGS.

lineNumber

O número da linha no modelo que causou essa alteração. Se a ação for, DELETE esse valor será nulo.

logicalResourceId

O ID lógico do recurso que está sendo alterado.

resourceType

O tipo de recurso que está sendo alterado.

Exemplo de entrada de alteração do conjunto de alterações do Lambda Hook

Veja a seguir um exemplo de entrada de alteração do conjunto de alterações. No exemplo a seguir, você pode ver as alterações introduzidas pelo conjunto de alterações. A primeira alteração é excluir uma fila chamada. CoolQueue A segunda mudança é adicionar uma nova fila chamadaNewCoolQueue. A última alteração é uma atualização doDynamoDBTable.

{ "clientRequestToken": "f8da6d11-b23f-48f4-814c-0fb6a667f50e", "awsAccountId": "123456789", "stackId": "arn:aws:cloudformation:eu-central-1:123456789:stack/david-ddb-test-stack/400b40f0-8e72-11ef-80ab-02f2902f0df1", "changeSetId": "arn:aws:cloudformation:eu-central-1:123456789:changeSet/davids-change-set/59ebd63c-7c89-4771-a576-74c3047c15c6", "hookTypeName": "my::lambda::changesethook", "hookTypeVersion": "00000008", "hookModel": { "LambdaFunction": "arn:aws:lambda:eu-central-1:123456789:function:changesethookfunction" }, "actionInvocationPoint": "CREATE_PRE_PROVISION", "requestData": { "targetName": "CHANGE_SET", "targetType": "CHANGE_SET", "targetLogicalId": "arn:aws:cloudformation:eu-central-1:123456789:changeSet/davids-change-set/59ebd63c-7c89-4771-a576-74c3047c15c6", "payload": "https://s3......" }, "requestContext": { "invocation": 1, "callbackContext": null } }

Este é um exemplo payload dorequestData.payload:

{ template: 'Resources:\n' + ' DynamoDBTable:\n' + ' Type: AWS::DynamoDB::Table\n' + ' Properties:\n' + ' AttributeDefinitions:\n' + ' - AttributeName: "PK"\n' + ' AttributeType: "S"\n' + ' BillingMode: "PAY_PER_REQUEST"\n' + ' KeySchema:\n' + ' - AttributeName: "PK"\n' + ' KeyType: "HASH"\n' + ' PointInTimeRecoverySpecification:\n' + ' PointInTimeRecoveryEnabled: false\n' + ' NewSQSQueue:\n' + ' Type: AWS::SQS::Queue\n' + ' Properties:\n' + ' QueueName: "NewCoolQueue"', changedResources: [ { logicalResourceId: 'SQSQueue', resourceType: 'AWS::SQS::Queue', action: 'DELETE', lineNumber: null, beforeContext: '{"Properties":{"QueueName":"CoolQueue"}}', afterContext: null }, { logicalResourceId: 'NewSQSQueue', resourceType: 'AWS::SQS::Queue', action: 'CREATE', lineNumber: 14, beforeContext: null, afterContext: '{"Properties":{"QueueName":"NewCoolQueue"}}' }, { logicalResourceId: 'DynamoDBTable', resourceType: 'AWS::DynamoDB::Table', action: 'UPDATE', lineNumber: 2, beforeContext: '{"Properties":{"BillingMode":"PAY_PER_REQUEST","AttributeDefinitions":[{"AttributeType":"S","AttributeName":"PK"}],"KeySchema":[{"KeyType":"HASH","AttributeName":"PK"}]}}', afterContext: '{"Properties":{"BillingMode":"PAY_PER_REQUEST","PointInTimeRecoverySpecification":{"PointInTimeRecoveryEnabled":"false"},"AttributeDefinitions":[{"AttributeType":"S","AttributeName":"PK"}],"KeySchema":[{"KeyType":"HASH","AttributeName":"PK"}]}}' } ] }

Exemplo de função Lambda para operações de conjunto de alterações

O exemplo a seguir é a segmentação do Lambda Hook. Node.js É uma função simples que baixa a carga útil da operação do conjunto de alterações, percorre cada alteração e, em seguida, imprime as propriedades antes e depois antes de retornar a. SUCCESS

export const handler = async (event, context) => { var payloadUrl = event?.requestData?.payload; var response = { "hookStatus": "SUCCESS", "message": "Change set changes are compliant", "clientRequestToken": event.clientRequestToken }; try { const changeSetHookPayloadRequest = await fetch(payloadUrl); const changeSetHookPayload = await changeSetHookPayloadRequest.json(); const changes = changeSetHookPayload.changedResources || []; for(const change of changes) { var beforeContext = {}; var afterContext = {}; if(change.beforeContext) { beforeContext = JSON.parse(change.beforeContext); } if(change.afterContext) { afterContext = JSON.parse(change.afterContext); } console.log(beforeContext) console.log(afterContext) // Evaluate Change here } } catch (error) { console.log(error); response.hookStatus = "FAILED"; response.message = "Failed to evaluate change set operation."; response.errorCode = "InternalFailure"; } return response; };