Назад | Перейти на главную страницу

Как исправить / почему условия вызывают неразрешенные зависимости ресурсов

редактировать

Оригинальные подробности ниже.

В процессе погони за этим я сузил круг вопросов до того факта, что эта группа безопасности

  DatabaseSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Condition: WantsMail
    Properties:
      GroupDescription: Security group for RDS Databases
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 3306
          ToPort: 3306
          SourceSecurityGroupId: !Ref MailSecurityGroup
      VpcId:
        !Ref Vpc

не создается, хотя WantsMail оценивается как true. Я знаю WantsMail оценивается как true потому что я изменил раздел "Выходы":

Outputs:
...
  DatabaseSecurityGroup:
    Condition: WantsMail
    Description: Security group for RDS database access
    Value: Foo
    Export:
      Name: FooName

Мало того, что это выводится правильно, но и MailSecurityGroup (что также зависит от WantsMail) создается. Однако у этой группы безопасности нет. Никаких ошибок YAML нет. Нет ошибок, которые я могу найти в пользовательском интерфейсе AWS CloudFormation. Есть идеи, что не так, или как отследить любую ошибку, которая может произойти?

В сторону: Правильно ли здесь делать такое редактирование? Или я должен был убить исходный вопрос и задать этот более конкретный, или ...?


Оригинальные детали

Я работаю над разбивкой моих шаблонов CloudFormation на функциональные стеки. Еще не до того, чтобы делать какие-либо вложения, просто делая все автономно. Для моего шаблона группы безопасности у меня есть кое-что очень простое, но когда я начинаю добавлять условия, я начинаю получать «Неразрешенные зависимости ресурсов ... в блоке выходных данных шаблона». Я не считать есть какие-либо опечатки, и это, наряду с тем, что связано с вложением, кажется, наиболее частые проблемы, которые я видел в других вопросах, подобных этому.

Базовый рабочий шаблон выглядит так:

---
AWSTemplateFormatVersion: 2010-09-09

Description: 'Create Security Groups'

Metadata:

  AWS::CloudFormation::Interface:
    ParameterGroups:
    - Label:
        default: AWS Parameters
      Parameters:
        - SshAccessCidr
        - Vpc
    ParameterLabels:
      SshAccessCidr:
        default: SSH Access From
      Vpc:
        default: Vpc Id

Parameters:

  SshAccessCidr:
    AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))$
    Description: The CIDR IP range that is permitted to SSH to bastion instance. Note - a value of 0.0.0.0/0 will allow access from ANY IP address.
    Type: String
    Default: 0.0.0.0/0
  Vpc:
    AllowedPattern: ^(vpc-)([a-z0-9]{8}|[a-z0-9]{17})$
    Description: The Vpc Id of an existing Vpc.
    Type: AWS::EC2::VPC::Id

Resources:

  BastionSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Security group for Bastion instances
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: !Ref SshAccessCidr
      VpcId:
        !Ref Vpc

  DatabaseSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Security group for RDS Databases
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 3306
          ToPort: 3306
          CidrIp: 10.0.0.0/20
      VpcId:
        !Ref Vpc

Outputs:
  BastionSecurityGroup:
    Value: !Ref BastionSecurityGroup
    Export:
      Name: !Join [ ":", [ !Ref "AWS::StackName", BastionSecurityGroup ] ]
  DatabaseSecurityGroup:
    Value: !Ref DatabaseSecurityGroup
    Export:
      Name: !Join [ ":", [ !Ref "AWS::StackName", DatabaseSecurityGroup ] ]

и, как я уже сказал, отлично работает!

Но когда я начинаю добавлять условия, он выходит из себя:

  AWS::CloudFormation::Interface:
    ParameterGroups:
...
    - Label:
        default: Optional security groups to create
      Parameters:
        - CreateMailSecGroup
    ParameterLabels:
...
      CreateMailSecGroup:
        default: Create a security group for mail servers

Parameters:
...
  CreateMailSecGroup:
    AllowedValues:
      - 'True'
      - 'False'
    Default: 'False'
    Description: Create a security group for use by mail servers
    Type: String

Conditions:

  WantsMail: !Equals ['True', !Ref CreateMailSecGroup]
  WantsNothing: !Not [ !Equals ['True', !Ref CreateMailSecGroup] ]

Resources:

  DatabaseSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Condition: WantsMail
    Properties:
      GroupDescription: Security group for RDS Databases
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 3306
          ToPort: 3306
          SourceSecurityGroupId: !Ref MailSecurityGroup
      VpcId:
        !Ref Vpc

  DatabaseSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Condition: WantsNothing
    Properties:
      GroupDescription: Security group for RDS Databases
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 3306
          ToPort: 3306
          CidrIp: 10.0.0.0/20
      VpcId:
        !Ref Vpc

  MailSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Condition: WantsMail
    Properties:
      GroupDescription: Security group for MX Servers
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          SourceSecurityGroupId: !Ref BastionSecurityGroup
        - IpProtocol: tcp
          FromPort: 25
          ToPort: 25
          CidrIp: 0.0.0.0/0
...
      VpcId:
        !Ref Vpc

Outputs:
...
  DatabaseSecurityGroup:
    Description: Security group for RDS database access
    Value: !Ref DatabaseSecurityGroup
    Export:
      Name: !Join [ ":", [ !Ref "AWS::StackName", DatabaseSecurityGroup ] ]
  MailSecurityGroup:
    Condition: WantsMail
    Description: Security group for MX servers
    Value: !Ref MailSecurityGroup
    Export:
      Name: !Join [ ":", [ !Ref "AWS::StackName", MailSecurityGroup ] ]

Теперь, если я внесу эти изменения и сделаю стек обновления в текущем (работающем) стеке и оставлю новый параметр CreateMailSecGroup по умолчанию False, он поступает правильно и говорит "ничего не менять" после анализа шаблона. Но если я изменю его на True, он жалуется

Неразрешенные зависимости ресурсов [DatabaseSecurityGroup] в блоке Outputs шаблона

в предварительном просмотре набора изменений.

Мое первоначальное подозрение заключалось в том, что теперь, когда DatabaseSecurityGroup является условной, она должна нуждаться в условии соответствия в блоке Outputs, поэтому я попробовал

Conditions:

  WantsMail: !Equals ['True', !Ref CreateMailSecGroup]
  WantsNothing: !Not [ !Equals ['True', !Ref CreateMailSecGroup] ]
  OutputDatabase: !Or [ Condition: WantsMail, Condition: WantsNothing ]
...
Outputs:
  DatabaseSecurityGroup:
    Condition: OutputDatabase
    Description: Security group for RDS database access
    Value: !Ref DatabaseSecurityGroup
    Export:
      Name: !Join [ ":", [ !Ref "AWS::StackName", DatabaseSecurityGroup ] ]

Никаких кубиков. Та же ошибка.

Мое последнее предположение заключалось в том, что, возможно, DatabaseSecurityGroup на самом деле не обрабатывалась с помощью True условие из-за какого-то странного явления упорядочивания, поэтому я попытался добавить DependsOn: MailSecurityGroup, но это тоже не помогло.

Я очень надеюсь, что это не глупая опечатка. У кого-нибудь есть идеи, что я делаю не так? Условие для MailSecurityGroup, похоже, не вызывает никаких ошибок, но я не уверен, потому что это не ошибка или потому, что он остановился в разделе выходов DatabaseSecurityGroup и так и не дошел до финала. один.

Спасибо!

Хмф. В соответствии с документация:

Логический идентификатор должен быть буквенно-цифровым (A-Za-z0-9) и уникальным в пределах шаблона.

И простой, и надоедливый. Таким образом, нельзя иметь два разных ресурса с именем «DatabaseSecurityGroup» и переключаться между ними в зависимости от условий. Необходимо дать им разные имена (а затем в выходных данных создать несколько выходных разделов для разных имен, которые также выбираются в зависимости от условий).