Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .changelog/45005.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
resource/aws_instance: Add option to preserve state after attribute changes which require EC2 start/stop
```
28 changes: 22 additions & 6 deletions internal/service/ec2/ec2_instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,12 @@ func resourceInstance() *schema.Resource {
Optional: true,
AtLeastOneOf: []string{names.AttrInstanceType, names.AttrLaunchTemplate},
},
"preserve_powerstate": {
Type: schema.TypeBool,
Computed: false,
Optional: true,
Default: false,
},
"ipv6_address_count": {
Type: schema.TypeInt,
Optional: true,
Expand Down Expand Up @@ -1552,6 +1558,8 @@ func resourceInstanceUpdate(ctx context.Context, d *schema.ResourceData, meta an
}
}

preservePowerstate := d.Get("preserve_powerstate").(bool)

// See also CustomizeDiff.
if d.HasChanges(names.AttrInstanceType, "user_data", "user_data_base64") && !d.IsNewResource() {
// For each argument change, we start and stop the instance
Expand All @@ -1568,7 +1576,7 @@ func resourceInstanceUpdate(ctx context.Context, d *schema.ResourceData, meta an
},
}

if err := modifyInstanceAttributeWithStopStart(ctx, conn, &input, fmt.Sprintf("InstanceType (%s)", instanceType)); err != nil {
if err := modifyInstanceAttributeWithStopStart(ctx, conn, &input, fmt.Sprintf("InstanceType (%s)", instanceType), preservePowerstate); err != nil {
return sdkdiag.AppendErrorf(diags, "updating EC2 Instance (%s) type: %s", d.Id(), err)
}
}
Expand All @@ -1593,7 +1601,7 @@ func resourceInstanceUpdate(ctx context.Context, d *schema.ResourceData, meta an
},
}

if err := modifyInstanceAttributeWithStopStart(ctx, conn, &input, "UserData"); err != nil {
if err := modifyInstanceAttributeWithStopStart(ctx, conn, &input, "UserData", preservePowerstate); err != nil {
return sdkdiag.AppendErrorf(diags, "updating EC2 Instance (%s) user data: %s", d.Id(), err)
}
}
Expand All @@ -1613,7 +1621,7 @@ func resourceInstanceUpdate(ctx context.Context, d *schema.ResourceData, meta an
},
}

if err := modifyInstanceAttributeWithStopStart(ctx, conn, &input, "UserData (base64)"); err != nil {
if err := modifyInstanceAttributeWithStopStart(ctx, conn, &input, "UserData (base64)", preservePowerstate); err != nil {
return sdkdiag.AppendErrorf(diags, "updating EC2 Instance (%s) user data base64: %s", d.Id(), err)
}
}
Expand Down Expand Up @@ -2003,9 +2011,15 @@ func disableInstanceAPITermination(ctx context.Context, conn *ec2.Client, id str
// as input by first stopping the EC2 instance before the modification
// and then starting up the EC2 instance after modification.
// Reference: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Stop_Start.html
func modifyInstanceAttributeWithStopStart(ctx context.Context, conn *ec2.Client, input *ec2.ModifyInstanceAttributeInput, attrName string) error {
func modifyInstanceAttributeWithStopStart(ctx context.Context, conn *ec2.Client, input *ec2.ModifyInstanceAttributeInput, attrName string, preservePowerstate bool) error {
id := aws.ToString(input.InstanceId)

_, state, err := statusInstance(ctx, conn, id)()

if err != nil {
return err
}

if err := stopInstance(ctx, conn, id, false, instanceStopTimeout); err != nil {
return err
}
Expand All @@ -2014,8 +2028,10 @@ func modifyInstanceAttributeWithStopStart(ctx context.Context, conn *ec2.Client,
return fmt.Errorf("modifying EC2 Instance (%s) %s attribute: %w", id, attrName, err)
}

if err := startInstance(ctx, conn, id, true, instanceStartTimeout); err != nil {
return err
if !preservePowerstate || (strings.ToLower(state) != "stopped" && strings.ToLower(state) != "stopping") {
if err := startInstance(ctx, conn, id, true, instanceStartTimeout); err != nil {
return err
}
}

return nil
Expand Down
Loading