Устранение циклических зависимостей между AWS стеками CDK CloudFormation - PullRequest
1 голос
/ 19 февраля 2020

Контекст, у меня есть приложение CDK с двумя стеками, использующее следующую настройку:

Stack_A:
    StateMachine_A
    Lambda_A
    S3Bucket_A
    IAMRole_A

Stack_B:
    StateMachine_B
    SageMakerTrainJob_B
    IAMRole_B

StateMachine_A запускает Lambda_A с использованием роли выполнения IAMRole_A. Отдельный шаг в StateMachine_A записывает данные в S3Bucket_A. StateMachine_B запускает SageMakerTrainJob_B с использованием роли выполнения IAMRole_B. Целью Lambda_A является запуск выполнения StateMachine_B, чей SageMakerTrainJob_B должен читать из S3Bucket_A. Поэтому нам необходимо настроить следующие разрешения:

  • IAMRole_A нужны разрешения startExecution для StateMachine_B.
  • IAMRole_B нужны разрешения на чтение для S3Bucket_A.

Мы пытались смоделировать это в CDK, создав прямую зависимость в Stack_B для Stack_A, используя ссылки на IAMRole_A и S3Bucket_A в определении Stack_B для предоставления необходимых разрешений в коде. Однако это породило следующую ошибку:

Error: 'Stack_B' depends on 'Stack_A' (dependency added using stack.addDependency()). Adding this dependency (Stack_A -> Stack_B/IAMRole_B/Resource.Arn) would create a cyclic reference.

Аналогичным образом, попытка смоделировать зависимость в другом направлении привела к той же ошибке:

Error: 'Stack_A' depends on 'Stack_B' (dependency added using stack.addDependency()). Adding this dependency (Stack_B -> Stack_A/S3Bucket_A/Resource.Arn) would create a cyclic reference.

Есть ли способ обойти это, используя зависимости кода? Есть ли рекомендуемые лучшие практики для подобных ситуаций? Некоторые варианты, которые мы рассмотрели, включают:

  • Использование третьего стека, который зависит как от предоставления Stack_A, так и Stack_B доступа к ресурсам друг друга.
  • Создание дополнительных ролей доступа для необходимых ресурсов внутри каждого стека и поддерживая разрешения acceptRole для ролей Lambda / SageMaker где-то за пределами CDK.
  • Помещение их всех в один стек. Не подходит для организации и делает ресурсы действительно тесно связанными - мы можем не захотеть, чтобы StateMachine_A была единственной точкой входа в StateMachine_B в будущем.

Кроме того, я вижу, что во время схожих проблем Разработка CDK с CodeCommit / CodePipeline и APIGateway / Lambda . Это связанная ошибка, или мы просто пытаемся сделать что-то, что не поддерживается?

1 Ответ

0 голосов
/ 26 февраля 2020

Циркулярные ссылки всегда сложно. Это не проблема, которая уникальна для CDK. Когда вы объясняете проблему логически, вы видите, где все начинает разрушаться. CloudFormation должен создать любые ресурсы, от которых зависит другой ресурс, прежде чем он сможет создать зависимый ресурс. Не существует единого решения, подходящего для всех подходов, но я дам несколько идей, которые сработают.

  1. Продвижение общих ресурсов в другой стек. В вашем случае корзина S3 должна использоваться обоими стеками, поэтому, если она находится в стеке, который выполняется до того, как вы сможете создать сегмент S3, используйте экспорт / импорт в стеке B для ссылки на корзину S3, а также используйте и экспортируйте / import в стеке A для ссылки на сегмент S3 и конечный автомат в B.
  2. Использование подстановочных знаков в разрешениях. Часто вы можете знать имя или достаточно имени ресурса, чтобы использовать подстановочные знаки в ваших разрешениях. Вы хотите, чтобы права доступа были строго ограничены, но довольно часто частичное совпадение имен является достаточно хорошим. Разумеется, используйте эту опцию с осторожностью. Также имейте в виду, что многие ресурсы могут быть названы вами. Многие предпочитают не делать этого никогда, а некоторые ресурсы вам не следует (например, S3), но я часто нахожу, что проще называть вещи.
  3. Создайте пользовательский ресурс для t ie вещей вместе. Если у вас есть истинная круговая зависимость, которая не может быть разрешена (даже в одном и том же стеке), вам может потребоваться использовать собственный ресурс, чтобы выполнить эту работу за вас. Ярким примером этого является S3 bucket events .
...