aws-cloudformation / aws-cloudformation/cloudformation-coverage-roadmap

Fn::GetAtt: and !GetAtt behaves differently during an Update Operation and Import Operation

Open
#1,045 0 comments 1 reaction 0 assignees View on GitHub
bug enhancement
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.