редактировать
Оригинальные подробности ниже.
В процессе погони за этим я сузил круг вопросов до того факта, что эта группа безопасности
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» и переключаться между ними в зависимости от условий. Необходимо дать им разные имена (а затем в выходных данных создать несколько выходных разделов для разных имен, которые также выбираются в зависимости от условий).