Вопрос или проблема
У меня есть существующий пул пользователей Cognito, который я создал вручную в консоли AWS. Недавно я добавил его в свой шаблон CloudFormation, чтобы другие ресурсы в моем стеке могли на него ссылаться, но я не хочу, чтобы CloudFormation изменял или удалял его. Однако каждый раз, когда я разворачиваю свой шаблон, я вижу следующую группу изменений, указывающую на то, что пул пользователей Cognito помечен для удаления:
Изменения стека CloudFormation
-----------------------------------------------------------------------------------------------------------------------------------------------------
Операция ЛогическийИдентификаторРесурса ТипРесурса Замена
-----------------------------------------------------------------------------------------------------------------------------------------------------
* Изменить WebSocketConnectFunction AWS::Lambda::Function Нет
* Изменить WebSocketConnectIntegration AWS::ApiGatewayV2::Integration Нет
* Изменить WebSocketDefaultFunction AWS::Lambda::Function Нет
* Изменить WebSocketDefaultIntegration AWS::ApiGatewayV2::Integration Нет
* Изменить WebSocketDisconnectFunction AWS::Lambda::Function Нет
* Изменить WebSocketDisconnectIntegration AWS::ApiGatewayV2::Integration Нет
- Удалить CognitoUserPool AWS::Cognito::UserPool Н/Д
template.yaml:
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: Бекенд веб-приложения
Parameters:
ExistingCognitoUserPoolId:
Type: String
Description: Идентификатор существующего пула пользователей Cognito
Default: ap-example-2_aKzfw0K4N
Resources:
WebSocketApi:
Type: AWS::ApiGatewayV2::Api
Properties:
Name: WebSocketAPI
ProtocolType: WEBSOCKET
RouteSelectionExpression: $request.body.action
WebSocketConnectIntegration:
Type: AWS::ApiGatewayV2::Integration
Properties:
ApiId: !Ref WebSocketApi
IntegrationType: AWS_PROXY
IntegrationUri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${WebSocketConnectFunction.Arn}/invocations
WebSocketDisconnectIntegration:
Type: AWS::ApiGatewayV2::Integration
Properties:
ApiId: !Ref WebSocketApi
IntegrationType: AWS_PROXY
IntegrationUri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${WebSocketDisconnectFunction.Arn}/invocations
WebSocketDefaultIntegration:
Type: AWS::ApiGatewayV2::Integration
Properties:
ApiId: !Ref WebSocketApi
IntegrationType: AWS_PROXY
IntegrationUri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${WebSocketDefaultFunction.Arn}/invocations
WebSocketConnectRoute:
Type: AWS::ApiGatewayV2::Route
Properties:
ApiId: !Ref WebSocketApi
RouteKey: $connect
AuthorizationType: NONE
Target: !Sub integrations/${WebSocketConnectIntegration}
WebSocketDisconnectRoute:
Type: AWS::ApiGatewayV2::Route
Properties:
ApiId: !Ref WebSocketApi
RouteKey: $disconnect
AuthorizationType: NONE
Target: !Sub integrations/${WebSocketDisconnectIntegration}
WebSocketDefaultRoute:
Type: AWS::ApiGatewayV2::Route
Properties:
ApiId: !Ref WebSocketApi
RouteKey: $default
AuthorizationType: NONE
Target: !Sub integrations/${WebSocketDefaultIntegration}
WebSocketConnectFunction:
Type: AWS::Serverless::Function
Properties:
Handler: server.wsConnectHandler
Runtime: nodejs18.x
CodeUri: .
Tracing: Active
OnConnectPermission:
Type: AWS::Lambda::Permission
Properties:
Action: lambda:InvokeFunction
FunctionName: !Ref WebSocketConnectFunction
Principal: apigateway.amazonaws.com
WebSocketDisconnectFunction:
Type: AWS::Serverless::Function
Properties:
Handler: server.wsDisconnectHandler
Runtime: nodejs18.x
CodeUri: .
Tracing: Active
OnDisconnectPermission:
Type: AWS::Lambda::Permission
Properties:
Action: lambda:InvokeFunction
FunctionName: !Ref WebSocketDisconnectFunction
Principal: apigateway.amazonaws.com
WebSocketDefaultFunction:
Type: AWS::Serverless::Function
Properties:
Handler: server.wsDefaultHandler
Runtime: nodejs18.x
CodeUri: .
Tracing: Active
Timeout: 900
Policies:
- Statement:
Effect: Allow
Action:
- execute-api:ManageConnections
Resource:
- !Sub arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${WebSocketApi}/Test/POST/@connections/*
OnDefaultPermission:
Type: AWS::Lambda::Permission
Properties:
Action: lambda:InvokeFunction
FunctionName: !Ref WebSocketDefaultFunction
Principal: apigateway.amazonaws.com
Outputs:
WebSocketApiUrl:
Value: !Sub wss://${WebSocketApi}.execute-api.${AWS::Region}.amazonaws.com/Stage
Description: URL веб-сайта WebSocket API
CognitoUserPoolId:
Value: !Ref ExistingCognitoUserPoolId
Description: Идентификатор существующего пула пользователей Cognito
Ответ или решение
Чтобы избежать удаления вручную созданного пула пользователей Cognito во время развертывания стека CloudFormation, вам необходимо выполнить несколько шагов, чтобы CloudFormation не пытался управлять этим ресурсом. Ваша проблема заключается в том, что CloudFormation считает ресурс, который вы добавили в шаблон, частью управления стеком и пытается выполнить с ним какие-либо действия.
Вот шаги, которые следует предпринять:
-
Используйте AWS::Cognito::UserPool с параметрами: Вместо того, чтобы определять пул пользователей прямо в шаблоне, вы можете передать идентификатор существующего пула пользователей как параметр. Данный подход позволит сохранить идентификатор пула пользователей, созданного вручную, и избежать его изменения.
-
Корректное использование параметров: Вам необходимо убедиться, что вы используете параметры корректно и не ссылаетесь на существующий пул пользователей как на ресурс, который должен управляться CloudFormation. Убедитесь, что вы используете полученный параметр для других ресурсов, которые его требуют, а не создаете новый пул пользователей в самом шаблоне.
Изменение шаблона
Вот как ваш шаблон может выглядеть с учетом вышесказанного:
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: Web Application Backend
Parameters:
ExistingCognitoUserPoolId:
Type: String
Description: ID of the existing Cognito User Pool
Resources:
WebSocketApi:
Type: AWS::ApiGatewayV2::Api
Properties:
Name: WebSocketAPI
ProtocolType: WEBSOCKET
RouteSelectionExpression: $request.body.action
# Ссылки на существующий пул пользователей.
WebSocketConnectFunction:
Type: AWS::Serverless::Function
Properties:
Handler: server.wsConnectHandler
Runtime: nodejs18.x
CodeUri: .
Tracing: Active
Environment:
CognitoUserPoolId: !Ref ExistingCognitoUserPoolId # Передайте идентификатор пула
# Остальные ресурсы...
Имеется в виду:
- Убедитесь, что в
Outputs
вашего шаблона вы также ссылаетесь на параметрExistingCognitoUserPoolId
, чтобы упростить его использование другими ресурсами и не создавать новый пул, который CloudFormation попытается удалить.
Проверка изменений:
- Перед тем как развернуть шаблон, воспользуйтесь командой
aws cloudformation create-change-set
и проанализируйте изменения, чтобы убедиться, что пул пользователей Cognito не помечен для удаления.
Заключение
С помощью передачи идентификатора существующего пула пользователей как параметры и правильной настройки зависимостей для других ресурсов, вы сможете избежать изменений и удаления вашего вручную созданного пула пользователей Cognito во время развертывания стека CloudFormation.