Repository: basti-app/basti (language: python)

Issue:
Failure to update basti-instance image
## Bug Description

When updating AMI reference in CDK, stack upgrade fails because role cannot be updated

## Steps to Reproduce

1. Change bastion image reference, here in Python

```
             id=basti_instance_id,
             vpc=vpc,
             vpc_subnets=subnets,
+            # Most recent minimal to reduce vulnerability risk
+            machine_image=ec2.MachineImage.from_ssm_parameter(
+                "/aws/service/ami-amazon-linux-latest/al2023-ami-minimal-kernel-default-x86_64"
+            ),
             # Defaults t2.micro not available in ZH eu-central-2 Region
             instance_type=ec2.InstanceType.of(ec2.InstanceClass.T3, ec2.InstanceSize.MICRO)
             )
```

2. Check cdk diff Bastion

```
Stack Bastion
Parameters
[-] Parameter SsmParameterValueawsserviceamiamazonlinuxlatestamzn2amikernel510hvmx8664gp2C96584B6F00A464EAD1953AFF4B05118Parameter: {"Type":"AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>","Default":"/aws/service/ami-amazon-linux-latest/amzn2-ami-kernel-5.10-hvm-x86_64-gp2"}
[+] Parameter SsmParameterValue:--aws--service--ami-amazon-linux-latest--al2023-ami-minimal-kernel-default-x86_64:C96584B6-F00A-464E-AD19-53AFF4B05118.Parameter SsmParameterValueawsserviceamiamazonlinuxlatestal2023amiminimalkerneldefaultx8664C96584B6F00A464EAD1953AFF4B05118Parameter: {"Type":"AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>","Default":"/aws/service/ami-amazon-linux-latest/al2023-ami-minimal-kernel-default-x86_64"}

Resources
[~] AWS::IAM::Role basti-instance/IamRoleBastionInstance bastiinstanceIamRoleBastionInstance748FE39E replace
 └─ [+] Path (requires replacement)
     └─ /basti/eu-central-2/
[~] AWS::EC2::Instance basti-instance/Ec2InstanceBastion bastiinstanceEc2InstanceBastionC84AB388 replace
 ├─ [+] BlockDeviceMappings (may cause replacement)
 │   └─ [{"DeviceName":"/dev/xvda","Ebs":{"Encrypted":true}}]
 ├─ [~] ImageId (requires replacement)
 │   └─ [~] .Ref:
 │       ├─ [-] SsmParameterValueawsserviceamiamazonlinuxlatestamzn2amikernel510hvmx8664gp2C96584B6F00A464EAD1953AFF4B05118Parameter
 │       └─ [+] SsmParameterValueawsserviceamiamazonlinuxlatestal2023amiminimalkerneldefaultx8664C96584B6F00A464EAD1953AFF4B05118Parameter
 └─ [~] Tags
     └─ @@ -9,7 +9,7 @@
        [ ] },
        [ ] {
        [ ]   "Key": "basti:in-use",
        [-]   "Value": "2024-10-04T12:18:37.519Z"
        [+]   "Value": "2024-10-22T11:39:14.878Z"
        [ ] },
        [ ] {
        [ ]   "Key": "Environment",


✨  Number of stacks with differences: 1
```

3. Deploy but fails

```
Bastion: creating CloudFormation changeset...
Bastion | 0/7 | 9:23:11 AM | UPDATE_IN_PROGRESS   | AWS::CloudFormation::Stack     | Bastion User Initiated
Bastion | 0/7 | 9:23:14 AM | CREATE_IN_PROGRESS   | AWS::CDK::Metadata             | CDKMetadata/Default (CDKMetadata) 
Bastion | 0/7 | 9:23:15 AM | UPDATE_FAILED        | AWS::IAM::Role                 | basti-instance/IamRoleBastionInstance (bastiinstanceIamRoleBastionInstance748FE39E) CloudFormation cannot update a stack when a custom-named resource requires replacing. Rename basti-instance-cfa6c72d and update the stack again.
Bastion | 0/7 | 9:23:15 AM | CREATE_FAILED        | AWS::CDK::Metadata             | CDKMetadata/Default (CDKMetadata) Resource creation cancelled
Bastion | 0/7 | 9:23:15 AM | UPDATE_ROLLBACK_IN_P | AWS::CloudFormation::Stack     | Bastion The following resource(s) failed to create: [CDKMetadata]. The following resource(s) failed to update: [bastiinstanceIamRoleBastionInstance748FE39E]. 
Bastion | 1/7 | 9:23:17 AM | UPDATE_COMPLETE      | AWS::IAM::Role                 | basti-instance/IamRoleBastionInstance (bastiinstanceIamRoleBastionInstance748FE39E) 
Bastion | 2/7 | 9:23:19 AM | UPDATE_ROLLBACK_COMP | AWS::CloudFormation::Stack     | Bastion 
Bastion | 3/7 | 9:23:20 AM | DELETE_COMPLETE      | AWS::CDK::Metadata             | CDKMetadata/Default (CDKMetadata) 
Bastion | 4/7 | 9:23:20 AM | UPDATE_ROLLBACK_COMP | AWS::CloudFormation::Stack     | Bastion
```

## Possible Solution (Optional)

I am expecting at least guidance in documentation how to update basti-instance base image to fix vulnerabilities



Discussion / hints:
Hi @ymartin59, thank you for reporting this bug! I think this error is connected to a recent change I made which blocks the update - https://github.com/basti-app/basti/pull/109/files#diff-b5a46dba7e3da24b7e9a6416e5dd8cc03c8ca8399d5ac09dc942d8aa71faa1fbR145 (added the role path in basti-cdk@1.0.4)

You have three options:

1. Recreate the Basti stack with the latest version (basti-cdk@1.1.0)
2. Use the version before the breaking change to update the existing stack (basti-cdk@1.0.3)
3. Wait for the fix I plan to release tomorrow. The fix will allow to update the existing stack with the latest version of basti-cdk 

Fix patch:
diff --git a/packages/basti-cdk/src/basti-instance.ts b/packages/basti-cdk/src/basti-instance.ts
index 34bfdeb..e7f3251 100644
--- a/packages/basti-cdk/src/basti-instance.ts
+++ b/packages/basti-cdk/src/basti-instance.ts
@@ -147,7 +147,7 @@ export class BastiInstance extends Construct implements IBastiInstance {
 
     this.role = new aws_iam.Role(this, 'IamRoleBastionInstance', {
       assumedBy: new aws_iam.ServicePrincipal('ec2.amazonaws.com'),
-      roleName: `${BASTION_INSTANCE_ROLE_NAME_PREFIX}-${this.bastiId}`,
+      roleName: `${BASTION_INSTANCE_ROLE_NAME_PREFIX}-${this.bastiId}-v2`,
       path: `${BASTION_INSTANCE_ROLE_PATH_PREFIX}/${region}/`,
       inlinePolicies: {
         'session-manager-access': sessionManagerPolicy,


Test patch:
diff --git a/packages/basti-cdk/src/__test__/basti-instance.test.ts b/packages/basti-cdk/src/__test__/basti-instance.test.ts
index 93496ab..b2ee0fb 100644
--- a/packages/basti-cdk/src/__test__/basti-instance.test.ts
+++ b/packages/basti-cdk/src/__test__/basti-instance.test.ts
@@ -31,7 +31,7 @@ describe('BastiInstanceTest', () => {
     });
 
     template.hasResourceProperties('AWS::IAM::Role', {
-      RoleName: 'basti-instance-d8b7dc8b',
+      RoleName: 'basti-instance-d8b7dc8b-v2',
       AssumeRolePolicyDocument: {
         Statement: [
           {
@@ -163,7 +163,7 @@ describe('BastiInstanceTest', () => {
     });
 
     template.hasResourceProperties('AWS::IAM::Role', {
-      RoleName: 'basti-instance-TEST_ID',
+      RoleName: 'basti-instance-TEST_ID-v2',
       AssumeRolePolicyDocument: {
         Statement: [
           {