Open asilverman opened 2 years ago
We propose to mark all primaryIdentifier and additionalIdentifier properties that are not readOnlyProperties to be flagged as ObjectPropertyFlags.Required. Doing so will restrict the author to specify a value for these properties so that AWS CloudFormation generation logic is never used as a guardrail to prevent creating non-idempotent bicep manifests.
This sounds like the right solution to me 👍
FYI in case you're interested - this is just background and I think you already have the right idea:
One of the fundamental benefits of describing an application model in .bicep manifests is that their deployment to a given radius environment is idempotent
Bicep is somewhat unique in this regard in that it's stateless. Terraform, Pulumi, and Cloud Formation are all fundamentally stateful, and thus can all support non-idempotent operations. This is not without drawbacks of course, because adding state adds its own challenges.
The combo of Bicep + Stacks is stateful, and in-theory could support non-idempotent operations. Right now there's no way for a Bicep user to say "I will only use this file with stacks" so there's no desire to expose non-idempotency to users. This might change someday 😆
Overview
Every AWS resource type has a property that is defined as its
primary identifier
. The value of this property must be unique for each resource of that type in a given AWS account and AWS Region. For example, many resource types include aName
property that must be unique for each resource of that type. In some cases, theprimary identifier
is defined as a combination of multiple properties that together form a unique identifier. By using thisprimary identifier
, combined with the resource type, you can specify exactly which resource on which you want to perform resource operations such asupdate-resource
ordelete-resource
.In addition, some resource types define
secondary identifiers
that can also be used to uniquely identify resources of that type.To determine which resource property (or combination of properties) is the primary identifier for a resource type, refer to the
primaryIdentifier
attribute of the resource type schema. When the resource type includes secondary identifiers, refer to theadditionalIdentifiers
attribute of the resource type schema.During the exploration to model AWS Resources with Bicep using the AWS Bicep Extensibility Provider types, we noticed that often the
primaryIdentifier
attributes of a resource are not required to be specified during resource creation as illustrated by Example 1.Example 1
Consider a
AWS::Kinesis::Stream
resource, below are the relevant schema properties (see here for the full schema description)From the JSON schema it follows that
Name
belongs to bothcreateOnlyProperties
andprimaryIdentifier
.Notice that this schema in particular doesn't define the
required
attribute so theName
property isn't required to be specified for resource creation.Further inspection of the resource type
Name
property in CloudFormation documentation reveals that AWS CloudFormation generates a stream name on your behalf if you don't choose to specify a value.In addition, notice that
Name
property of the resource cannot be updated, so specifying aName
that wasn't previously assigned will result in a new resource being created. A special case is when the value is unspecified which will result in AWS CloudFormation generating a unique name for the resource.Description of
Name
property (source: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-kinesis-stream.html#cfn-kinesis-stream-name)The Problem
One of the fundamental benefits of describing an application model in
.bicep
manifests is that their deployment to a given radius environment is idempotent, however, an operator authoring their AWS infrastructure in Bicep to be consumed by a Radius application developer may inadvertently define theAWS::Kinesis::Stream
resource without aName
property since there are no guardrails against it in the Bicep type definition breaking the idempotency promise and resulting in the creation of potentially undesired cloud resources that litter the customers AWS account.Proposed Solution
The
types.json
generator for AWS Resources visits the CloudFormation schema to produce the Bicep Extensibility Resource schema (see code section for full details).We propose to mark all
primaryIdentifier
andadditionalIdentifier
properties that are notreadOnlyProperties
to be flagged asObjectPropertyFlags.Required
. Doing so will restrict the author to specify a value for these properties so that AWS CloudFormation generation logic is never used as a guardrail to prevent creating non-idempotent bicep manifests.Tasks
convert.ts
Additional Information
In the issue Background we mention that the logic of auto generation of
primaryIdentifier
properties is a common occurrence, to support this argument we will keep below a running list of resources for which this applies.More can be found by running the following google query.
Helpful information about CloudFormation field generation behavior - https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-name.html AB#4487