aws-cloudformation / aws-cloudformation/cloudformation-coverage-roadmap
Fn::GetAtt: and !GetAtt behaves differently during an Update Operation and Import Operation
- Dominant language
- No language data
- Stars
- 1.1k
- Forks
- 62
- PR merge metrics
- No merged PRs in 30d
Description
### Name of the resource
Other
### Resource Name
_No response_
### Issue Description
Documentation for [Fn::GetAtt](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-getatt.html) intrinsic function shows that either the YAML full syntax `Fn::GetAtt:` or the shorthand `!GetAtt` can be used in a CloudFormation template and should expectedly return the attribute value of specified resource.
However, when a Stack is created and either the !GetAtt or Fn::GetAtt: is specified for a resource, changing this to either the full syntax or shorthand results in a modification of the resource(s) and an update. The update type ChangeSet shows the resource is modified. In actual fact, the value of the resource property wasn't changed and therefore should not cause an update.
Also, for importing existing resources, the below error is observed when the syntax is modified either to full syntax or shorthand on an existing resource in the template:
```
There was an error creating this change set
You have modified resources [ResourceName] in your template that are not being imported. Update, create or delete operations cannot be executed during import operations.
```
This prevents one from being able to import the resource to the CloudFormation Stack.
### Expected Behavior
**UpdateStack:**
During the UpdateStack operation, expected behavior is CloudFormation to display: `No updates are to be performed`
**Import Operation:**
Expected behavior is to import the existing resource(s) into CloudFormation Stack successfully.
### Observed Behavior
**UpdateStack:**
The Observed behavior is that a change of the `Fn::GetAtt` syntax either to a YAML full syntax `Fn::GetAtt:` or shorthand `!GetAtt` returns as a modification to the property value of the resource it is specified under, thereby displaying a modification to the resource in a ChangeSet with no causing entity.
**Import Operation:**
If importing a new resource to the CloudFormation template and a modification is made to this intrinsic function on an existing resource in the template either to a YAML full syntax `Fn::GetAtt:` or shorthand `!GetAtt`, it prevents importing the new resource with error:
```
There was an error creating this change set
You have modified resources [ResourceName] in your template that are not being imported. Update, create or delete operations cannot be executed during import operations.
```
### Test Cases
**UpdateStack:**
Launch a CloudFormation Stack with the below template:
```
Resources:
Ec2Instance:
Type: AWS::EC2::Instance
Properties:
ImageId: ami-xxxx
SubnetId: subnet-xxxx
AvailabilityZone: us-east-1d
Volume:
Type: AWS::EC2::Volume
Properties:
Size: 100
VolumeType: gp2
AvailabilityZone:
Fn::GetAtt:
- Ec2Instance
- AvailabilityZone
```
Then, once stack is created successfully, modify the template and change the value of property `AvailabilityZone` in resource type `AWS::EC2::Volume` to `!GetAtt Ec2Instance.AvailabilityZone`, then you will observe the following in the ChangeSet result:
```
[
{
"resourceChange": {
"logicalResourceId": "Volume",
"action": "Modify",
"physicalResourceId": "vol-xxxxxxxx",
"resourceType": "AWS::EC2::Volume",
"replacement": "False",
"moduleInfo": null,
"details": [
{
"target": {
"name": "AvailabilityZone",
"requiresRecreation": "Never",
"attribute": "Properties"
},
"causingEntity": null,
"evaluation": "Static",
"changeSource": "DirectModification"
}
],
"changeSetId": null,
"scope": [
"Properties"
]
},
"hookInvocationCount": null,
"type": "Resource"
}
]
```
**Import Operation:**
Using the same template as above, then add a new resource in the CloudFormation template with the attributes of the existing resource you want to import and also modify the `Fn::GetAtt` intrinsic function in the template to use the shorthand syntax `!GetAtt`. For example:
```
Resources:
Ec2Instance:
Type: AWS::EC2::Instance
Properties:
ImageId: ami-xxxx
SubnetId: subnet-xxxx
AvailabilityZone: us-east-1d
Volume:
Type: AWS::EC2::Volume
Properties:
Size: 100
VolumeType: gp2
AvailabilityZone: !GetAtt Ec2Instance.AvailabilityZone
MyTopic:
Type: AWS::SNS::Topic
Properties:
TopicName: TestTopic
```
This will prevent you from importing the new resource `MyTopic` with below error:
```
There was an error creating this change set
You have modified resources [Volume] in your template that are not being imported. Update, create or delete operations cannot be executed during import operations.
```
### Other Details
_No response_
Contributor guide
Research direction
Start with the linked Fn::GetAtt documentation and reproduce the behavior using the supplied UpdateStack and import-operation templates. Compare full and shorthand syntax in the ChangeSet results; done means UpdateStack reports no updates and the existing resource can be imported successfully without the modified resource error.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- aws
- Domain
- cloud, infrastructure
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 30/100