É essencial garantir a conformidade nas aplicações com tecnologia sem servidor o mais cedo possível no processo de desenvolvimento. Neste tópico, abordaremos como implementar controles preventivos usando o AWS Config. Isso permite que você implemente verificações de conformidade mais cedo no processo de desenvolvimento e implemente os mesmos controles nos seus pipelines de CI/CD. Isso também padroniza os controles em um repositório de regras gerenciado de forma centralizada para que você possa aplicar os controles de forma consistente em todas as suas contas da AWS.
Por exemplo, suponha que os administradores de conformidade tenham definido um requisito para garantir que todas as funções do Lambda incluam rastreamento do AWS X-Ray. Com o modo proativo do AWS Config, você pode executar verificações de conformidade nos recursos da função do Lambda antes da implantação, reduzindo o risco de implantar funções do Lambda configuradas incorretamente e economizando o tempo dos desenvolvedores ao fornecer feedback mais rápido sobre a infraestrutura como modelos de código. A seguir, é apresentada uma visualização do fluxo de controles preventivos com o AWS Config:
Considere a exigência de que todas as funções do Lambda tenham o rastreamento ativado. Em resposta, a equipe da plataforma identifica a necessidade de uma regra do AWS Config específica ser executada de forma proativa em todas as contas. Essa regra sinaliza qualquer função do Lambda que não tenha uma configuração de rastreamento do X-Ray configurada como um recurso fora de conformidade. A equipe desenvolve uma regra, coloca-a em um pacote de conformidade e implanta o pacote de conformidade em todas as contas da AWS para garantir que todas as contas da organização apliquem uniformemente esses controles. Você pode criar a regra na sintaxe AWS CloudFormation Guard 2.x.x, que assume o seguinte formato:
rule name when condition { assertion }
Veja a seguir um exemplo de regra do Guard que verifica se as funções do Lambda têm o rastreamento habilitado:
rule lambda_tracing_check {
when configuration.tracingConfig exists {
configuration.tracingConfig.mode == "Active"
}
}
A equipe da plataforma toma medidas adicionais ao exigir que cada implantação do AWS CloudFormation invoque um hook pré-criação/atualização. A equipe assume total responsabilidade pelo desenvolvimento desse hook e pela configuração do pipeline, fortalecendo o controle centralizado das regras de conformidade e sustentando a aplicação consistente delas em todas as implantações. Para desenvolver, empacotar e registrar um hook, consulte Desenvolver hooks do AWS CloudFormation na documentação da interface de linha de comando do CloudFormation (CFN-CLI). Você pode usar a CLI do CloudFormation para criar o projeto do hook:
cfn init
Esse comando solicita a você algumas informações básicas sobre o projeto do hook e cria um projeto com os seguintes arquivos:
README.md
<hook-name>
.json rpdk.log src/handler.py template.yml hook-role.yaml
Como desenvolvedor de hooks, você precisa adicionar o tipo de recurso de destino desejado no arquivo de configuração <hook-name>.json
. Na configuração abaixo, um hook é configurado para ser executado antes que qualquer função do Lambda seja criada usando o CloudFormation. Você também pode adicionar manipuladores semelhantes para ações de preUpdate
e preDelete
.
"handlers": { "preCreate": { "targetNames": [ "AWS::Lambda::Function" ], "permissions": [] } }
Você também precisa garantir que o hook do CloudFormation tenha as permissões apropriadas para chamar as APIs do AWS Config. Você pode fazer isso atualizando o arquivo de definição de perfil denominado hook-role.yaml
. Por padrão, o arquivo de definição de perfil tem a política de confiança a seguir, que permite que o CloudFormation assuma o perfil.
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- hooks.cloudformation.amazonaws.com
- resources.cloudformation.amazonaws.com
Para permitir que esse hook chame APIs de configuração, você deve adicionar as permissões a seguir à declaração da política. Em seguida, você envia o projeto do hook usando o comando cfn submit
, em que o CloudFormation cria um perfil para você com as permissões necessárias.
Policies:
- PolicyName: HookTypePolicy
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- "config:Describe*"
- "config:Get*"
- "config:List*"
- "config:SelectResourceConfig"
Resource: "*
Em seguida, você precisa criar uma função do Lambda em um arquivo src/handler.py
. Nesse arquivo, você encontra métodos denominados preCreate
, preUpdate
e preDelete
já criados quando você iniciou o projeto. Seu objetivo é criar uma função comum e reutilizável que chame a API StartResourceEvaluation
do AWS Config no modo proativo usando o AWS SDK para Python (Boto3). Essa chamada de API usa as propriedades do recurso como entrada e avalia o recurso em relação à definição da regra.
def validate_lambda_tracing_config(resource_type, function_properties: MutableMapping[str, Any]) -> ProgressEvent:
LOG.info("Fetching proactive data")
config_client = boto3.client('config')
resource_specs = {
'ResourceId': 'MyFunction',
'ResourceType': resource_type,
'ResourceConfiguration': json.dumps(function_properties),
'ResourceConfigurationSchemaType': 'CFN_RESOURCE_SCHEMA'
}
LOG.info("Resource Specifications:", resource_specs)
eval_response = config_client.start_resource_evaluation(EvaluationMode='PROACTIVE', ResourceDetails=resource_specs, EvaluationTimeout=60)
ResourceEvaluationId = eval_response.ResourceEvaluationId
compliance_response = config_client.get_compliance_details_by_resource(ResourceEvaluationId=ResourceEvaluationId)
LOG.info("Compliance Verification:", compliance_response.EvaluationResults[0].ComplianceType)
if "NON_COMPLIANT" == compliance_response.EvaluationResults[0].ComplianceType:
return ProgressEvent(status=OperationStatus.FAILED, message="Lambda function found with no tracing enabled : FAILED", errorCode=HandlerErrorCode.NonCompliant)
else:
return ProgressEvent(status=OperationStatus.SUCCESS, message="Lambda function found with tracing enabled : PASS.")
Agora, você pode chamar a função comum do manipulador para o hook de pré-criação. Veja um exemplo do manipulador:
@hook.handler(HookInvocationPoint.CREATE_PRE_PROVISION)
def pre_create_handler(
session: Optional[SessionProxy],
request: HookHandlerRequest,
callback_context: MutableMapping[str, Any],
type_configuration: TypeConfigurationModel
) -> ProgressEvent:
LOG.info("Starting execution of the hook")
target_name = request.hookContext.targetName
LOG.info("Target Name:", target_name)
if "AWS::Lambda::Function" == target_name:
return validate_lambda_tracing_config(target_name,
request.hookContext.targetModel.get("resourceProperties")
)
else:
raise exceptions.InvalidRequest(f"Unknown target type: {target_name}")
Após essa etapa, você poderá registrar o hook e configurá-lo para ouvir todos os eventos de criação de funções do AWS Lambda.
Um desenvolvedor prepara o modelo de infraestrutura como código (IaC) para um microsserviço com tecnologia sem servidor usando o Lambda. Essa preparação inclui a adesão aos padrões internos, seguida pelo teste local e pela confirmação do modelo para o repositório. Veja um exemplo de modelo de IaC:
MyLambdaFunction:
Type: 'AWS::Lambda::Function'
Properties:
Handler: index.handler
Role: !GetAtt LambdaExecutionRole.Arn
FunctionName: MyLambdaFunction
Code:
ZipFile: |
import json
def handler(event, context):
return {
'statusCode': 200,
'body': json.dumps('Hello World!')
}
Runtime: python3.13
TracingConfig:
Mode: PassThrough
MemorySize: 256
Timeout: 10
Como parte do processo de CI/CD, quando o modelo do CloudFormation é implantado, o serviço do CloudFormation invoca o hook de pré-criação/atualização logo antes de provisionar o tipo de recurso da AWS::Lambda::Function
. O hook utiliza regras do AWS Config executadas no modo proativo para verificar se a configuração da função do Lambda inclui a configuração de rastreamento obrigatória. A resposta do hook determina a próxima etapa. Se estiver em conformidade, o hook indicará êxito e o CloudFormation continuará a provisionar os recursos. Caso contrário, a implantação da pilha do CloudFormation apresentará falha, o pipeline será interrompido imediatamente e o sistema registrará os detalhes para análise posterior. As notificações de conformidade são enviadas aos investidores relevantes.
Você pode encontrar as informações de êxito/falha do hook no console do CloudFormation:
Se você tiver logs habilitados para o hook do CloudFormation, poderá capturar o resultado da avaliação do hook. Veja um exemplo de log de um hook com status de falha, indicando que a função do Lambda não tem o X-Ray ativado:
Se o desenvolvedor optar por alterar a IaC para atualizar o valor de TracingConfig Mode
para Active
e reimplantar, o hook será executado com êxito e a pilha prosseguirá com a criação do recurso do Lambda.
Dessa forma, você pode implementar controles preventivos com o AWS Config em modo proativo ao desenvolver e implantar recursos com tecnologia sem servidor nas suas contas da AWS. Ao integrar regras do AWS Config ao pipeline de CI/CD, você pode identificar e, opcionalmente, bloquear implantações de recursos fora de conformidade, como funções do Lambda que não possuem uma configuração de rastreamento ativa. Isso garante que somente recursos em conformidade com as políticas de governança mais recentes sejam implantados nos ambientes da AWS.