简体   繁体   中英

How to conditionally create s3 bucket in cloudformation?

We have a cloud formation stack that contains data storage resources like RDS,S3. We want to preserve them even if the stack is deleted or when upgrading the stack, few parameters can cause the services to re-create. so we have set a deletion policy to retain . Now when I re-run the stack it is unable to create the resources because the resources with the same name exist.

I thought of creating the resources by checking if it exists or not. Is it possible for cloud formation to have this check by itself. I also realized the retained resources have become rouge resources as they are not now part of this cloud formation.

What would be the best approach to get around this solution?

You have to import these buckets back into your stack.

Sadly CFN does not have functionality to check if something exists or not, and perform the import automatically by itself. So you have to do it manually using AWS console or programmatically using SDK or CLI.

This is a complex question in general, and without knowledge of your setup and specific CF template, it's hard to give specific advice. I will address some general points and suggested actions.

  1. "when I re-run the stack it is unable to create the resources because the resources with the same name exist" - This is common problem with named resources. As a general guidance, avoid statically naming those resources, with which no human operators will interact. If you have strict naming convention in place, then always add random suffix to names, which will make them unique to that stack.

  2. If you have storage resources, ie S3 buckets and DBs, then consider putting them into separate CF stack and expose relevant attributes (like DB endpoint address) as CF exports . You can reference them in other stacks by using Fn::ImportValue . This way you can separate "stable" resources from "volatile" ones and still have benefits of CF.

  3. You can import some existing resources into CF stacks. They will act as a legitimate part of the stack. But not all resources can be imported like this.

I think yes you can do this by putting a condition in your CFN whether in JSON/YAML

{
"AWSTemplateFormatVersion": "2010-09-09",
"Transform": "AWS::Serverless-2016-10-31",
"Description": "",
"Parameters": {
    "ShouldCreateBucketInputParameter": {
      "Type": "String",
      "AllowedValues": [
        "true",
        "false"
      ],
      "Description": "If true then the S3 bucket that will be proxied will be created with the CloudFormation stack."
    }
},
"Conditions": {
  "CreateS3Bucket": {
    "Fn::Equals": [
      {
        "Ref": "ShouldCreateBucketInputParameter"
      },
      "true"
    ]
  }
},
"Resources": {
    "SerialNumberBucketResource": {
        "Type": "AWS::S3::Bucket",
        "Condition": "CreateS3Bucket",
        "Properties": {
            "AccessControl": "Private"
        }
    }
  }   
}

And then using CLI you just need to set "true" or "false"

aws cloudformation deploy --template ./s3BucketWithCondition.json --stack-name bucket-stack --parameter-overrides ShouldCreateBucketInputParameter="true"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM