How can I automatically add termination protection to stacks launched using service catalog?

0

Hi,

We are launching stacks using service catalog (via the Java client, as it happens). We'd like to enable termination protection for each stack that gets launched.

I'm struggling to find out how... possibilities:

  • It's a parameter to the provision product API call - but I can't see it if so
  • It's defined in the product's definition - but I can't see where if so
  • We should turn it on with a subsequent API call after the product is provisioned?

Just to muddy the waters further, we actually create the product stack and the product via the Java CDK - there is actually a a setTerminationProtection setter on software.amazon.awscdk.services.servicecatalog.ProductStack but setting it to true doesn't actually affect the CloudFormation template that gets generated 🤷‍♂️.

  • Trying the third option, but just getting from the result of serviceCatalogClient.provisionProduct to an actual cloudformation stack in the AWS SDK v2 seems to be a labour of Hercules - bafflingly complicated.

1 Answer
0
Accepted Answer

Edit - updated to retry until the stack arn is present on the record outputs...

The only solution I've so far found is to set it immediately after creation using the SDK.

import software.amazon.awssdk.services.cloudformation.CloudFormationClient
import software.amazon.awssdk.services.cloudformation.model.UpdateTerminationProtectionRequest
import software.amazon.awssdk.services.servicecatalog.ServiceCatalogClient
import software.amazon.awssdk.services.servicecatalog.model.DescribeRecordRequest
import software.amazon.awssdk.services.servicecatalog.model.ProvisionProductRequest
import java.time.Duration
import java.time.Instant.now

val serviceCatalogClient = ServiceCatalogClient.create()
val cloudFormationClient = CloudFormationClient.create()

val provisionProductResponse = serviceCatalogClient.provisionProduct(ProvisionProductRequest.builder()
   // TODO add params!
  .build()
)

var stackArn: String? = null
val timeout = now() + Duration.ofSeconds(20)

while (stackArn == null && now() < timeout) {
  Thread.sleep(Duration.ofSeconds(1).toMillis())
  val record = serviceCatalogClient.describeRecord(DescribeRecordRequest.builder()
    .id(provisionProductResponse.recordDetail().recordId())
    .build()
  )
  stackArn = record
    .recordOutputs()
    ?.singleOrNull { it.outputKey() == "CloudformationStackARN" }
    ?.outputValue()
}

if (stackArn != null) {
  cloudFormationClient.updateTerminationProtection(UpdateTerminationProtectionRequest.builder()
    .stackName(stackArn)
    .enableTerminationProtection(true)
    .build()
  )
}
answered 7 months ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions