@@ -406,37 +406,65 @@ func NewAWSSessionWithKey(accessKey *iam.AccessKey) client.ConfigProvider {
406
406
// createCloudFormationStack ensures the cloudformation stack is up to date.
407
407
func createCloudFormationStack (prov client.ConfigProvider , t * cfn_bootstrap.Template , tags map [string ]string ) error {
408
408
By (fmt .Sprintf ("Creating AWS CloudFormation stack for AWS IAM resources: stack-name=%s" , t .Spec .StackName ))
409
- CFN := cfn .New (prov )
410
- cfnSvc := cloudformation .NewService (CFN )
411
-
412
- Eventually (func () bool {
413
- err := cfnSvc .ReconcileBootstrapStack (t .Spec .StackName , * renderCustomCloudFormation (t ), tags , true )
414
- if err != nil {
415
- By (fmt .Sprintf ("Error reconciling Cloud formation stack %v" , err ))
409
+ cfnClient := cfn .New (prov )
410
+ // CloudFormation stack will clean up on a failure, we don't need an Eventually here.
411
+ // The `create` already does a WaitUntilStackCreateComplete.
412
+ cfnSvc := cloudformation .NewService (cfnClient )
413
+ err := cfnSvc .ReconcileBootstrapNoUpdate (t .Spec .StackName , * renderCustomCloudFormation (t ), tags )
414
+ if err != nil {
415
+ By (fmt .Sprintf ("Error reconciling Cloud formation stack %v" , err ))
416
+ spewCloudFormationResources (cfnClient , t )
417
+
418
+ stack , derr := cfnClient .DescribeStacks (& cfn.DescribeStacksInput {StackName : aws .String (t .Spec .StackName )})
419
+ if derr == nil && len (stack .Stacks ) > 0 {
420
+ if aws .StringValue (stack .Stacks [0 ].StackStatus ) == cfn .StackStatusRollbackFailed ||
421
+ aws .StringValue (stack .Stacks [0 ].StackStatus ) == cfn .StackStatusRollbackComplete ||
422
+ aws .StringValue (stack .Stacks [0 ].StackStatus ) == cfn .StackStatusRollbackInProgress ||
423
+ aws .StringValue (stack .Stacks [0 ].StackStatus ) == cfn .StackStatusCreateFailed ||
424
+ aws .StringValue (stack .Stacks [0 ].StackStatus ) == cfn .StackStatusDeleteFailed {
425
+ // If cloudformation stack creation fails due to resources that already exist, stack stays in rollback status and must be manually deleted.
426
+ // Delete resources that failed because they already exists.
427
+ By ("Starting cleanup process as the stack failed to create" )
428
+ deleteMultitenancyRoles (prov )
429
+ deleteResourcesInCloudFormation (prov , t )
430
+ }
416
431
}
417
- output , err1 := CFN .DescribeStackEvents (& cfn.DescribeStackEventsInput {StackName : aws .String (t .Spec .StackName ), NextToken : aws .String ("1" )})
432
+ return err
433
+ }
434
+
435
+ spewCloudFormationResources (cfnClient , t )
436
+ return err
437
+ }
438
+
439
+ func spewCloudFormationResources (cfnClient * cfn.CloudFormation , t * cfn_bootstrap.Template ) {
440
+ output , err := cfnClient .DescribeStackEvents (& cfn.DescribeStackEventsInput {StackName : aws .String (t .Spec .StackName ), NextToken : aws .String ("1" )})
441
+ if err != nil {
442
+ By (fmt .Sprintf ("Error describin Cloud formation stack events %v, skipping" , err ))
443
+ } else {
418
444
By ("========= Stack Event Output Begin =========" )
419
445
for _ , event := range output .StackEvents {
420
446
By (fmt .Sprintf ("Event details for %s : Resource: %s, Status: %s, Reason: %s" , aws .StringValue (event .LogicalResourceId ), aws .StringValue (event .ResourceType ), aws .StringValue (event .ResourceStatus ), aws .StringValue (event .ResourceStatusReason )))
421
447
}
422
448
By ("========= Stack Event Output End =========" )
423
- return err == nil && err1 == nil
424
- }, 2 * time .Minute ).Should (Equal (true ))
425
-
426
- stack , err := CFN .DescribeStacks (& cfn.DescribeStacksInput {StackName : aws .String (t .Spec .StackName )})
427
- if err == nil && len (stack .Stacks ) > 0 {
428
- deleteMultitenancyRoles (prov )
429
- if aws .StringValue (stack .Stacks [0 ].StackStatus ) == cfn .StackStatusRollbackFailed ||
430
- aws .StringValue (stack .Stacks [0 ].StackStatus ) == cfn .StackStatusRollbackComplete ||
431
- aws .StringValue (stack .Stacks [0 ].StackStatus ) == cfn .StackStatusRollbackInProgress ||
432
- aws .StringValue (stack .Stacks [0 ].StackStatus ) == cfn .StackStatusCreateFailed ||
433
- aws .StringValue (stack .Stacks [0 ].StackStatus ) == cfn .StackStatusDeleteFailed {
434
- // If cloudformation stack creation fails due to resources that already exist, stack stays in rollback status and must be manually deleted.
435
- // Delete resources that failed because they already exists.
436
- deleteResourcesInCloudFormation (prov , t )
449
+ }
450
+ out , err := cfnClient .DescribeStackResources (& cfn.DescribeStackResourcesInput {
451
+ StackName : aws .String (t .Spec .StackName ),
452
+ })
453
+ if err != nil {
454
+ By (fmt .Sprintf ("Error describing Stack Resources %v, skipping" , err ))
455
+ } else {
456
+ By ("========= Stack Resources Output Begin =========" )
457
+ By ("Resource\t Type\t Status" )
458
+
459
+ for _ , r := range out .StackResources {
460
+ By (fmt .Sprintf ("%s\t %s\t %s\t %s" ,
461
+ aws .StringValue (r .ResourceType ),
462
+ aws .StringValue (r .PhysicalResourceId ),
463
+ aws .StringValue (r .ResourceStatus ),
464
+ aws .StringValue (r .ResourceStatusReason )))
437
465
}
466
+ By ("========= Stack Resources Output End =========" )
438
467
}
439
- return err
440
468
}
441
469
442
470
func SetMultitenancyEnvVars (prov client.ConfigProvider ) error {
0 commit comments