问题
I have a CF parent template with nested stacks in it. What I'm trying to do is set DependsOn attribute in one of the nested stacks, to check for the resource from another nested stack.
Here is my setup:
Parent stack: (Passing the resource reference between nested stacks)
RDS:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: https://cf-app-stack.s3.eu-west-2.amazonaws.com/infrastructure/rds.yaml
Parameters:
EnvironmentName: !Ref AWS::StackName
DBVPCSecurityGroup: !GetAtt SecurityGroups.Outputs.DBVPCSecurityGroup
PrivateSubnet1: !GetAtt VPC.Outputs.PrivateSubnet1
PrivateSubnet2: !GetAtt VPC.Outputs.PrivateSubnet2
ECS:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: https://cf-app-stack.s3.eu-west-2.amazonaws.com/infrastructure/ecs-cluster.yaml
Parameters:
EnvironmentName: !Ref AWS::StackName
MasterDB: !GetAtt RDS.Outputs.MasterDB
InstanceType: t2.micro
ClusterSize: 1
VPC: !GetAtt VPC.Outputs.VPC
SecurityGroup: !GetAtt SecurityGroups.Outputs.ECSHostSecurityGroup
Subnets: !GetAtt VPC.Outputs.PrivateSubnets
nested RDS stack: (exports the DB resource ref)
MasterDB:
Type: AWS::RDS::DBInstance
Properties:
DBSnapshotIdentifier: arn:aws:rds:eu-west-2:731152906121:snapshot:db-starter-image
AllocatedStorage: !Ref DBAllocatedStorage
DBInstanceClass: !Ref DBInstanceClass
Engine: MySQL
# Some DB instance properties aren't valid when you restore from a snapshot, such as the MasterUsername and MasterUserPassword properties.
#MasterUsername: !Ref DBUser
#MasterUserPassword: !Ref DBPassword
MultiAZ: !Ref 'MultiAZ'
Tags:
- Key: Name
Value: !Sub ${EnvironmentName}-Database
DBSubnetGroupName: !Ref myDBSubnetGroup
VPCSecurityGroups: [ !Ref DBVPCSecurityGroup ]
DeletionPolicy: Snapshot
Outputs:
MasterDB:
Description: A reference to the created DB
Value: MasterDB
nested ECS stack: (I want this one to depend on the RDS instance from the above nested stack)
Parameters:
MasterDB:
Description: A reference to the created DB
Type: String
Resources:
ECSCluster:
Type: AWS::ECS::Cluster
Properties:
ClusterName: !Ref EnvironmentName
ECSAutoScalingGroup:
DependsOn: [ECSCluster, !Ref MasterDB]
Type: AWS::AutoScaling::AutoScalingGroup
Properties:
VPCZoneIdentifier: !Ref Subnets
LaunchConfigurationName: !Ref ECSLaunchConfiguration
MinSize: !Ref ClusterSize
MaxSize: !Ref ClusterSize
DesiredCapacity: !Ref ClusterSize
Tags:
- Key: Name
Value: !Sub ${EnvironmentName} ECS host
PropagateAtLaunch: true
See "DependsOn: [ECSCluster, !Ref MasterDB]" in the above code. Am I doing this wrong? I tried other variations trying to satisfy DependsOn but so far no luck.
回答1:
You don't really need to use DependsOn for you specific Scenario and I think this attribute doesn't even support referring to resources outside of the stack. The reason is that in order to reference a value in a nested stack, it needs to be passed in from Output attributes from another stack. And just passing an Output parameter to a nested stack makes this stack dependent on the other nested stack it was exported from - and that alone achieves your goal.
Taking your code,
nested ECS stack:
Parameters:
MasterDB:
Description: Make this stack dependent on RDS resource
Type: String
That's all you need to do, the parameter does not even need to be used anywhere in the nested stack.
So if one stack is dependent on another, they can only be executed and completed top to bottom, one after another.
For example if:
Stack A: accepts Attr1 Output from stack B
and
Stack B: accepts Attr2 Output from stack A
The above will always fail, because regardless of which stack will be executed first, the Attr param it is dependent on will not be ready.
来源:https://stackoverflow.com/questions/57959202/aws-cloudformation-how-to-dependson-resource-from-another-nested-stack