How to set semi-random name for S3 bucket using cloud formation

You have two options.

First option - you can just leave your BucketName property blank. When you leave it blank, it'll yield a name of: <stackname>-<template logical name>-<random suffix>

So, if you have stack name and template logical name that make sense, it should give you a unique bucket name every time.

Second option - use the Stack ARN suffix, which is a random guid: arn:aws:cloudformation:us-west-2:123456789012:stack/teststack/51af3dc0-da77-11e4-872e-1234567db123

!Select [2, !Split [/, !Ref AWS::StackId ]]

That would yield you '51af3dc0-da77-11e4-872e-1234567db123' You can further split that again and select a portion if you want.

!Select [0, !Split[-, !Select [2, !Split [/, !Ref AWS::StackId ]]]]

Gives you 51af3dc0


Thanks Phillip Mattheson and Sleeper Smith for your excellent answers! I wanted to provide an alternative (and somewhat easier to read IMHO) method for producing the same results. I prefer to use !Sub over !Join whenever possible (see this great blog post for more info):

  BucketWithSemiRandomName:
    Type: AWS::S3::Bucket
    Properties:
      BucketName:
        !Sub
          - 'bucket-with-semi-random-name-${RandomGUID}'
          - { RandomGUID: !Select [0, !Split ["-", !Select [2, !Split ["/", !Ref AWS::StackId ]]]] }

Thanks Sleeper Smith. This is a great answer and i have been looking for a solution to this for awhile!


tl;dr

yaml CloudFormation below returns "bucket-with-semi-random-name-51af3dc0"

BucketWithSemiRandomName:
  Type: "AWS::S3::Bucket"
  Properties:
    BucketName: !Join
      - "-"
      - - "bucket-with-semi-random-name"
        - !Select
          - 0
          - !Split
            - "-"
            - !Select
              - 2
              - !Split
                - "/"
                - !Ref "AWS::StackId"

Slight index error in the code sample provided Sleeper Smith. You will need to replace the select index as below.

Using the same example Stack ARN as original answer...

arn:aws:cloudformation:us-west-2:123456789012:stack/teststack/51af3dc0-da77-11e4-872e-1234567db123
!Select [2, !Split [/, !Ref AWS::StackId ]]

Above code sample returns UUID (index 2) from Stack ARN "51af3dc0-da77-11e4-872e-1234567db123"

!Select [0, !Split[-, !Select [2, !Split [/, !Ref AWS::StackId ]]]]

Above code sample returns first segment (index 0) of UUID from Stack ARN "51af3dc0"


This is the resulting yaml that i am now using based on Sleeper Smith's answer. I've combined a !Join to provide more context to the bucket name.

BucketWithSemiRandomName:
  Type: "AWS::S3::Bucket"
  Properties:
    BucketName: !Join
      - "-"
      - - "bucket-with-semi-random-name"
        - !Select
          - 0
          - !Split
            - "-"
            - !Select
              - 2
              - !Split
                - "/"
                - !Ref "AWS::StackId"

Above code sample returns "bucket-with-semi-random-name-51af3dc0"