cfn-language-discussion
cfn-language-discussion copied to clipboard
Parameter extensions / Parameter types for resource types.
Name of the resource
Other
Resource name
No response
Description
Currently CloudFormation supports a limited list of AWS-specific parameter types. It would be a very useful to have parameter types for:
- every resource type that implements a List handler
- private parameter types
It could even go a step further and resolv attributes of those resources
Examples:
# Returns the primary identifier
Type: AWS::CloudFormation::Stack::$id
# Selection options for multiple primary identifiers
Type: List<AWS::CloudFormation::Stack::$id>
# Using a private resource type
Type: Type: MyCompany::Service::Product::$id
# Returns the !GetAtt StackSetId of the selected resource (selection still via primary identifier)
# Note: this might be confusing, but querying all Attributes seems unfeasable
Type: AWS::CloudFormation::StackSet::StackSetId
Type: List<AWS::CloudFormation::StackSet::StackSetId>
Of course alternative syntax is also possible. Eg.
# primary identifiers
Type: CloudControl<AWS::CloudFormation::Stack>
Type: CloudControlList<AWS::CloudFormation::Stack>
# GetAtt
Type: CloudControlAttribute<AWS::CloudFormation::StackSet, StackSetId>
Type: CloudControlAttributeList<AWS::CloudFormation::StackSet, StackSetId>
Other Details
This is probably extra powerful when used in Service Catalog
I don't think this should require types that implement list handlers, nor should it need a specification of a property within a resource type. The parameter type should just be the resource type itself and the input value required in the stack operation is the primary identifier as defined in the schema, and then the input name is referenceable like a normal resource. The list handler, if it's defined, is used by the AWS console to provide a dropdown of primary identifiers.
The template would look like:
Parameters:
Role:
Type: AWS::IAM::Role
Resources:
Function:
Type: AWS::Lambda::Function
Properties:
Role: !GetAtt Role.Arn
# etc
and then CreateStack
requires a role ARN as a parameter value.
Same with lists of types, e.g. List<AWS::IAM::Role>
; a syntax for referencing resources within the list could be common with the Fn::Map
proposal in aws-cloudformation/cfn-language-discussion#41.
parameter type should just be the resource type itself and the input value required in the stack operation is the primary identifier as defined in the schema, and then the input name is referenceable like a normal resource
I think that's a great idea.
The only use case that neither of our proposals captures is specifying a resource by a non-primary identifier. I didn't include it, because that wouldn't work with the List handler output. If you're skipping that (and rely on the read handler only), it would be nice to be able to do this:
Parameters:
TopicName:
Type: AWS::SNS::Topic
AllowedPattern: `[A-Za-z0-9]+` # The read handler will also throw an error if the resource does not exist
ConstraintDescription: Please only specify the name, not the full ARN
# a more generic "ResourceTransform" might also be useful for resources that don't expect an arn,
# but where you want the parameter to be one - although that is tricky if a cross-region ARN is pasted
ResourceSub: "arn:${AWS::Partition}:sns:${AWS::Region}:${AWS::AccountId}:${TopicName}"
There are some places where you can't do this (eg. you need an extra id for AWS::CloudFormation::Stack
), but other resources might benefit from this, so that either all parameters are ARNs, or none of them are.
Side note on the ResourceTransform and specifying the wrong region:
A ResourceMatch
could help with that, where it would throw a validationError if the values do not match:
Parameters:
RoleArn:
Type: AWS::Lambda::Function
# this will extract the Name to be used as identifier
# and throw an error if we're not matching regions/accounts
ResourceMatch: arn:${AWS::Partition}:lambda:${AWS::Region}:${AWS::AccountId}:([a-zA-Z0-9-_]+).*
The only use case that neither of our proposals captures is specifying a resource by a non-primary identifier.
I think this would be something the UI would handle, because you have to pick which non-primary identifier you'd specify by, and then it could issue a read call to get the primary identifier.
Or it could be a part of the stack operation that you can either specific the parameter value as a string, or as an object with the non-primary identifier property name and value.
In an ideal world, it would. Most resources schemas don't specify additional identifiers, even if they exists, though.
@benbridts Thank you very much for your feedback! Since this repository is focused on resource coverage, I'm transferring this issue over to a new GitHub repository dedicated to CloudFormation template language issues.