首页 > 解决方案 > AWS Secrets Manager and Cloud Formation - can not create secret because it already exists

问题描述

I have a CF template with a simple secret inside, like this:

Credentials:
    Type: 'AWS::SecretsManager::Secret'
    Properties:
    Name: !Sub ${ProjectKey}.${StageName}.${ComponentId}.credentials
    Description: client credentials
    SecretString: !Sub 
        '{"client_id":"${ClientId}","client_secret":"${ClientSecret}"}'

The stack is created successfully and the secret is correctly generated.

However when I delete the stack and recreate it again I get the following error message:

The operation failed because the secret pk.stage.compid.credentials already exists. (Service: AWSSecretsManager; Status Code: 400; Error Code: ResourceExistsException; Request ID: ###)

I guess this is because the secret is not really deleted but only marked for deletion for x days.

It is possible to delete a secret immediately via CLI, but how can this be done within the CF Template?

I need to delete and recreate the stacks because it is part of a continous integration/delivery pipeline which is automatically triggered on source code commits.

标签: amazon-web-servicesstackamazon-cloudformationaws-secrets-manager

解决方案


通常,当您删除堆栈时,也应删除秘密;并且 CFN 执行上述立即删除。即使秘密计划在 CFN 堆栈之外删除,这也应该成功。

如果(在您的堆栈被删除之后)秘密是由另一个云形成堆栈创建的,或者在另一个 CI 管道中运行的相同测试重新创建了该秘密,您可能会看到此错误。此外,大多数 AWS 系统(包括 Secrets Manager)最终都是一致的,您可能会看到堆栈被删除和实际密钥删除之间存在延迟。如果您的测试运行得足够快,或者在多个测试中重复使用相同的秘密名称,则在下一次创建之前可能没有完成之前的删除。

我们在 CI 堆栈中遇到了类似的问题,我们解决它的方法是使用生成的每个测试随机名称。例如,您可以将随机前缀作为参数传递给堆栈,并使用它来构造名称(确保每个测试使用唯一的后缀)。

顺便说一句 - 您可以通过对密钥运行 get-secret-value 来测试密钥是否已计划删除或实际上不存在。如果计划删除它,您将看到错误“...您无法对密钥执行此操作,因为它已被删除”,而如果密钥实际被删除,您将看到“Secrets Manager 找不到指定的秘密”。如果您安排要删除的机密,然后使用 --force-delete-without-recovery 将其删除,您可能会看到两个状态之间存在短暂的多秒延迟。


推荐阅读