AWS CloudFormation Traits#

CloudFormation traits are used to describe Smithy resources and their components so they can be converted to CloudFormation Resource Schemas.

CloudFormation Resource Schemas are the standard method of modeling a resource provider for use within CloudFormation. Smithy's modeled resources, utilizing the traits below, can generate these schemas. Automatically generating schemas from a service's API lowers the effort needed to generate and maintain them, reduces the potential for errors in the translation, and provides a more complete depiction of a resource in its schema. These schemas can be utilized by the CloudFormation Command Line Interface to build, register, and deploy resource providers.

aws.cloudformation#cfnResource trait#

Summary
Indicates that a Smithy resource is a CloudFormation resource.
Trait selector
resource
Value type
structure

The aws.cloudformation#cfnResource trait is a structure that supports the following members:

Property Type Description
name string Provides a custom CloudFormation resource name. Defaults to the shape name of the shape ID of the targeted resource when generating CloudFormation resource schemas.
additionalSchemas list<shapeId> A list of additional shape IDs of structures that will have their properties added to the CloudFormation resource. Members of these structures with the same names MUST resolve to the same target. See Resource properties for more information.

The following example defines a simple resource that is also a CloudFormation resource:

$version: "2"

namespace smithy.example

use aws.cloudformation#cfnResource

@cfnResource
resource Foo {
    identifiers: {
        fooId: String
    }
}

Resources that have properties that cannot be automatically derived can use the additionalSchemas trait property to include them. This is useful if interacting with a resource requires calling non-lifecycle APIs or if some of the resource's properties cannot be automatically converted to CloudFormation properties.

The following example provides a name value and one structure shape in the additionalSchemas list.

$version: "2"

namespace smithy.example

use aws.cloudformation#cfnResource

@cfnResource(
    name: "Foo"
    additionalSchemas: [AdditionalFooProperties])
resource FooResource {
    identifiers: {
        fooId: String
    }
}

structure AdditionalFooProperties {
    barProperty: String
}

Resource properties#

Smithy will automatically derive property information for resources with the @aws.cloudformation#cfnResource trait applied.

A resource's properties include the resource's identifiers as well as the top level members of the resource's read operation output structure, put operation input structure, create operation input structure, update operation input structure, and any structures listed in the @cfnResource trait's additionalSchemas property. Members of these structures can be excluded by applying the aws.cloudformation#cfnExcludeProperty trait.

Important

Any members used to derive properties that are defined in more than one of the above structures MUST resolve to the same target.

See also

Refer to property mutability for more information on how the CloudFormation mutability of a property is derived.

aws.cloudformation#cfnExcludeProperty trait#

Summary
Indicates that structure member should not be included as a property in generated CloudFormation resource definitions.
Trait selector

structure > member

Any structure member

Value type
Annotation trait
Conflicts with
aws.cloudformation#cfnAdditionalIdentifier trait, aws.cloudformation#cfnMutability trait

The cfnExcludeProperty trait omits a member of a Smithy structure from the derived resource properties of a CloudFormation resource.

The following example defines a CloudFormation resource that excludes the responseCode property:

$version: "2"

namespace smithy.example

use aws.cloudformation#cfnExcludeProperty
use aws.cloudformation#cfnResource

@cfnResource
resource Foo {
    identifiers: {
        fooId: String
    }
    read: GetFoo
}

@readonly
@http(method: "GET", uri: "/foos/{fooId}", code: 200)
operation GetFoo {
    input: GetFooRequest
    output: GetFooResponse
}

@input
structure GetFooRequest {
    @httpLabel
    @required
    fooId: String
}

@output
structure GetFooResponse {
    fooId: String

    @httpResponseCode
    @cfnExcludeProperty
    responseCode: Integer
}

Property mutability#

Any property derived for a resource will have its mutability automatically derived as well. CloudFormation resource properties can have the following mutability settings:

  • Full - Properties that can be specified when creating, updating, or reading a resource.
  • Create Only - Properties that can be specified only during resource creation and can be returned in a read or list request.
  • Read Only - Properties that can be returned by a read or list request, but cannot be set by the user.
  • Write Only - Properties that can be specified by the user, but cannot be returned by a read or list request.
  • Create and Write Only - Properties that can be specified only during resource creation and cannot be returned in a read or list request.

Given the following model without mutability traits applied,

$version: "2"

namespace smithy.example

use aws.cloudformation#cfnResource

@cfnResource
resource Foo {
    identifiers: {
        fooId: String
    }
    create: CreateFoo
    read: GetFoo
    update: UpdateFoo
}

operation CreateFoo {
    input: CreateFooRequest
    output: CreateFooResponse
}

@input
structure CreateFooRequest {
    createProperty: ComplexProperty
    mutableProperty: ComplexProperty
    writeProperty: ComplexProperty
    createWriteProperty: ComplexProperty
}

@output
structure CreateFooResponse {
    fooId: String
}

@readonly
operation GetFoo {
    input: GetFooRequest
    output: GetFooResponse
}

@input
structure GetFooRequest {
    @required
    fooId: String
}

@output
structure GetFooResponse {
    fooId: String
    createProperty: ComplexProperty
    mutableProperty: ComplexProperty
    readProperty: ComplexProperty
}

@idempotent
operation UpdateFoo {
    input: UpdateFooRequest
}

@input
structure UpdateFooRequest {
    @required
    fooId: String

    mutableProperty: ComplexProperty
    writeProperty: ComplexProperty
}

structure ComplexProperty {
    anotherProperty: String
}

The computed resource property mutabilities are:

Name CloudFormation Mutability Reasoning
fooId Read only
  • Returned in the read lifecycle via GetFooResponse.
createProperty Create only
  • Specified in the create lifecycle via CreateFooRequest.
  • Returned in the read lifecycle via GetFooResponse.
mutableProperty Full
  • Specified in the create lifecycle via CreateFooRequest.
  • Returned in the read lifecycle via GetFooResponse.
  • Specified in the update lifecycle via UpdateFooRequest.
readProperty Read only
  • Returned in the read lifecycle via GetFooResponse.
writeProperty Write only
  • Specified in the update lifecycle via UpdateFooRequest.
createWriteProperty Create and write only
  • Specified in the create lifecycle via CreateFooRequest.

aws.cloudformation#cfnMutability trait#

Summary
Indicates an explicit CloudFormation mutability of the structure member when part of a CloudFormation resource.
Trait selector

structure > member

Any structure member

Value type
string that MUST be set to "full", "create", "create-and-read", "read", or "write".
Conflicts with
aws.cloudformation#cfnExcludeProperty trait

The cfnMutability trait overrides any derived mutability setting on a member. The values of the mutability trait have the following meanings:

Value Description
full Indicates that the CloudFormation property generated from this member can be specified by the user on create and update and can be returned in a read or list request.
create Indicates that the CloudFormation property generated from this member can be specified only during resource creation and cannot returned in a read or list request. This is equivalent to having both create only and write only CloudFormation mutability.
create-and-read Indicates that the CloudFormation property generated from this member can be specified only during resource creation and can be returned in a read or list request. This is equivalent to create only CloudFormation mutability.
read Indicates that the CloudFormation property generated from this member can be returned by a read or list request, but cannot be set by the user. This is equivalent to read only CloudFormation mutability.
write Indicates that the CloudFormation property generated from this member can be specified by the user, but cannot be returned by a read or list request. MUST NOT be set if the member is also marked with the aws.cloudformation#cfnAdditionalIdentifier trait. This is equivalent to write only CloudFormation mutability.

The following example defines a CloudFormation resource that marks the tags and barProperty properties as fully mutable:

$version: "2"

namespace smithy.example

use aws.cloudformation#cfnMutability
use aws.cloudformation#cfnResource

@cfnResource(additionalSchemas: [FooProperties])
resource Foo {
    identifiers: {
        fooId: String
    }
    create: CreateFoo
}

operation CreateFoo {
    input: CreateFooRequest
    output: CreateFooResponse
}

@input
structure CreateFooRequest {
    @cfnMutability("full")
    tags: TagList
}

@output
structure CreateFooResponse {
    fooId: String
}

structure FooProperties {
    @cfnMutability("full")
    barProperty: String
}

The following example defines a CloudFormation resource that marks the immutableSetting property as create and read only:

$version: "2"

namespace smithy.example

use aws.cloudformation#cfnMutability
use aws.cloudformation#cfnResource

@cfnResource(additionalSchemas: [FooProperties])
resource Foo {
    identifiers: {
        fooId: String
    }
}

structure FooProperties {
    @cfnMutability("create-and-read")
    immutableSetting: Boolean
}

The following example defines a CloudFormation resource that marks the updatedAt and createdAt properties as read only:

$version: "2"

namespace smithy.example

use aws.cloudformation#cfnMutability
use aws.cloudformation#cfnResource

@cfnResource(additionalSchemas: [FooProperties])
resource Foo {
    identifiers: {
        fooId: String
    }
    read: GetFoo
}

@readonly
operation GetFoo {
    input: GetFooRequest
    output: GetFooResponse
}

@input
structure GetFooRequest {
    @required
    fooId: String
}

@output
structure GetFooResponse {
    @cfnMutability("read")
    updatedAt: Timestamp
}

structure FooProperties {
    @cfnMutability("read")
    createdAt: Timestamp
}

The following example defines a CloudFormation resource that marks the derivable secret and password properties as write only:

$version: "2"

namespace smithy.example

use aws.cloudformation#cfnMutability
use aws.cloudformation#cfnResource

@cfnResource(additionalSchemas: [FooProperties])
resource Foo {
    identifiers: {
        fooId: String
    }
    create: CreateFoo
}

operation CreateFoo {
    input: CreateFooRequest
    output: CreateFooResponse
}

@input
structure CreateFooRequest {
    @cfnMutability("write")
    secret: String
}

@output
structure CreateFooResponse {
    fooId: String
}

structure FooProperties {
    @cfnMutability("write")
    password: String
}

aws.cloudformation#cfnName trait#

Summary
Allows a CloudFormation resource property name to differ from a structure member name used in the model.
Trait selector

structure > member

Any structure member

Value type
string

Given the following structure definition:

$version: "2"

namespace smithy.example

use aws.cloudformation#cfnName

structure AdditionalFooProperties {
    bar: String

    @cfnName("Tags")
    tagList: TagList
}

the following property names are derived from it:

"bar"
"Tags"

aws.cloudformation#cfnAdditionalIdentifier trait#

Summary
Indicates that the CloudFormation property generated from this member is an additional identifier for the resource.
Trait selector

structure > :test(member > string)

Any structure member that targets a string

Value type
Annotation trait
Validation
The cfnAdditionalIdentifier trait MUST NOT be applied to members with the aws.cloudformation#cfnMutability trait set to write or create.

Each cfnAdditionalIdentifier uniquely identifies an instance of the CloudFormation resource it is a part of. This is useful for resources that provide identifier aliases (for example, a resource might accept an ARN or customer provided alias in addition to its unique ID.)

cfnAdditionalIdentifier traits are ignored when applied outside of the input to an operation bound to the read lifecycle of a resource.

The following example defines a CloudFormation resource that has the fooAlias property as an additional identifier:

$version: "2"

namespace smithy.example

use aws.cloudformation#cfnAdditionalIdentifier
use aws.cloudformation#cfnResource

@cfnResource
resource Foo {
    identifiers: {
        fooId: String
    }
    read: GetFoo
}

@readonly
operation GetFoo {
    input: GetFooRequest
}

@input
structure GetFooRequest {
    @required
    fooId: String

    @cfnAdditionalIdentifier
    fooAlias: String
}

aws.cloudformation#cfnDefaultValue trait#

Summary
Indicates that the member annotated has a default value for that property of the CloudFormation resource. Thus, when this trait annotates an @output structure member, it indicates that the CloudFormation property generated from that member has a default value in the CloudFormation schema. This trait can be used to indicate that an output field with a value may return a default value assigned by the service.
Trait selector

resource > operation -[output]-> structure > member

Only applicable to members of @output operations

Value type
Annotation trait

Given the following example, because the backTrackWindow member is annotated with cfnDefaultValue, it can be derived that the backTrackWindow member has a default value in the CloudFormation schema for this resource.

$version: "2"

namespace smithy.example

use aws.cloudformation#cfnDefaultValue
use aws.cloudformation#cfnResource

// this is a very simplified example of AWS::RDS::DBCluster
@cfnResource
resource DBCluster {
    identifiers: { DBClusterIdentifier: String }
    properties: { backTrackWindow: Integer }
    read: DescribeDBCluster,
}

@output
structure DescribeDBClusterResponse {
    $DBClusterIdentifier

    // If the user has not specified backTrackWindow
    // upon create, a default value will still be
    // observed in the DescribeDBClusterResponse
    @cfnDefaultValue
    $backTrackWindow
}

Example model#

The above traits and behaviors culminate in the ability to generate CloudFormation Resource Schemas from a Smithy model. The following example model utilizes all of these traits to express how a complex Smithy resource can be annotated for CloudFormation resource generation.

Given the following model,

$version: "2"

namespace smithy.example

use aws.cloudformation#cfnDefaultValue
use aws.cloudformation#cfnAdditionalIdentifier
use aws.cloudformation#cfnExcludeProperty
use aws.cloudformation#cfnMutability
use aws.cloudformation#cfnResource

@cfnResource(additionalSchemas: [FooProperties])
resource Foo {
    identifiers: {
        fooId: String
    }
    create: CreateFoo
    read: GetFoo
    update: UpdateFoo
}

@http(method: "POST", uri: "/foos", code: 200)
operation CreateFoo {
    input: CreateFooRequest
    output: CreateFooResponse
}

@input
structure CreateFooRequest {
    @cfnMutability("full")
    tags: TagList

    @cfnMutability("write")
    secret: String

    fooAlias: String

    createProperty: ComplexProperty
    mutableProperty: ComplexProperty
    writeProperty: ComplexProperty
    createWriteProperty: ComplexProperty
}

@output
structure CreateFooResponse {
    fooId: String
}

@readonly
@http(method: "GET", uri: "/foos/{fooId}", code: 200)
operation GetFoo {
    input: GetFooRequest
    output: GetFooResponse
}

@input
structure GetFooRequest {
    @httpLabel
    @required
    fooId: String

    @httpQuery("fooAlias")
    @cfnAdditionalIdentifier
    fooAlias: String
}

@output
structure GetFooResponse {
    fooId: String

    @httpResponseCode
    @cfnExcludeProperty
    responseCode: Integer

    @cfnMutability("read")
    updatedAt: Timestamp

    @cfnDefaultValue
    fooAlias: String
    createProperty: ComplexProperty
    mutableProperty: ComplexProperty
    readProperty: ComplexProperty
}

@idempotent
@http(method: "PUT", uri: "/foos/{fooId}", code: 200)
operation UpdateFoo {
    input: UpdateFooRequest
}

@input
structure UpdateFooRequest {
    @httpLabel
    @required
    fooId: String

    fooAlias: String
    mutableProperty: ComplexProperty
    writeProperty: ComplexProperty
}

structure FooProperties {
    addedProperty: String

    @cfnMutability("full")
    barProperty: String

    @cfnName("Immutable")
    @cfnMutability("create-and-read")
    immutableSetting: Boolean

    @cfnMutability("read")
    createdAt: Timestamp

    @cfnMutability("write")
    password: String
}

structure ComplexProperty {
    anotherProperty: String
}

list TagList {
    member: String
}

The following CloudFormation resource information is computed:

Name CloudFormation Mutability Reasoning
addedProperty Full
  • Default mutability in FooProperties via additionalSchemas.
barProperty Full
  • @cfnMutability trait specified in FooProperties via additionalSchemas.
createProperty Create only
  • Specified in the create lifecycle via CreateFooRequest.
  • Returned in the read lifecycle via GetFooResponse.=
createWriteProperty Create and write only
  • Specified in the create lifecycle via CreateFooRequest.
createdAt Read only
  • @cfnMutability trait specified in FooProperties via additionalSchemas.
fooAlias Full + additional identifier
  • Specified in the create lifecycle via CreateFooRequest.
  • Returned in the read lifecycle via GetFooResponse.
  • Specified in the update lifecycle via UpdateFooRequest.
  • @cfnAdditionalIdentifier trait specified in GetFooRequest.
fooId Read only + primary identifier
  • Returned in the read lifecycle via GetFooResponse.
Immutable from immutableSetting Create only
  • @cfnMutability trait specified in FooProperties via additionalSchemas.
mutableProperty Full
  • Specified in the create lifecycle via CreateFooRequest.
  • Returned in the read lifecycle via GetFooResponse.
  • Specified in the update lifecycle via UpdateFooRequest.
password Write only
  • @cfnMutability trait specified in FooProperties via additionalSchemas.
readProperty Read only
  • Returned in the read lifecycle via GetFooResponse.
responseCode None
  • @cfnExcludeProperty trait specified in GetFooResponse.
secret Write only
  • @cfnMutability trait specified in CreateFooRequest.
tags Full
  • @cfnMutability trait specified in CreateFooRequest.
updatedAt Read only
  • @cfnMutability trait specified in GetFooResponse.
writeProperty Write only
  • Specified in the create lifecycle via CreateFooRequest.
  • Specified in the update lifecycle via UpdateFooRequest.