migrating to 1.0 won’t result in any deleting &amp...
# help
s
migrating to 1.0 won’t result in any deleting & replacing of resources, will it? sometimes CloudFormation wants to delete/replace something just because a resource name changes. I’m paranoid about it messing up something in production
t
I ran diffs against 3 projects and didn't have any significant changes
I'd suggest doing the same
s
cool, will do 👍
I got everything migrated properly, at least according to TypeScript. ran a diff.. mostly looks good! except last time this happened, it caused major mayhem:
Copy code
[~] AWS::ApiGatewayV2::Route Route_PATCH_--account-info RoutePATCHaccountinfo2805F041
 └─ [~] AuthorizerId
     └─ [~] .Fn::ImportValue:
         ├─ [-] prod-microservices-api-base:ExportsOutputRefRestApiHttpUserPoolAuthorizerF0D1F4E162D79766
         └─ [+] prod-microservices-api-base:ExportsOutputRefRestApiuserPoolAuthorizer4A82D71EEDB5D7AA
do I dare deploy this, and hope that it handles the renaming of this export as far as other stacks that depend on it?
I suppose I have no choice, since I can’t force it to use a specific name
I think I’ll deploy to dev first to see how it goes
yep, here we go:
Copy code
dev-microservices-api-base | CREATE_IN_PROGRESS | AWS::ApiGatewayV2::Authorizer | RestApiuserPoolAuthorizer4A82D71E
dev-microservices-api-base | DELETE_FAILED | AWS::ApiGatewayV2::Authorizer | RestApiHttpUserPoolAuthorizerF0D1F4E1 | Cannot delete authorizer 'HttpUserPoolAuthorizer', is referenced in route: GET /admin/coupons (Service: AmazonApiGatewayV2; Status Code: 409; Error Code: ConflictException; Request ID: 7feabecf-fed7-4da5-bcad-8250cb1f0324; Proxy: null)
ugh
all because the name of a resource changed. I hate you, CloudFormation! 😄
t
@Frank this might be somewhat common if people are reworking their authorizers
f
hmm.. @Sam Hulick can I see what ur authorizers definition looks like?
I just gave this a test. So this in v0.69.5:
Copy code
const authorizer = new HttpJwtAuthorizer("Authorizer", "<https://myorg.us.auth0.com>", {
  jwtAudience: ["UsGRQJJz5sDfPQDs6bhQ9Oc3hNISuVif"],
});

this.api = new sst.Api(this, "Api", {
  defaultAuthorizer: authorizer,
  defaultAuthorizationType: sst.ApiAuthorizationType.JWT,
  routes: {
    ...
  },
});
and this in v1.0.0-beta.9:
Copy code
new sst.Api(this, "Api", {
  authorizers: {
    Authorizer: {
      type: "jwt",
      jwt: {
        issuer: "<https://myorg.us.auth0.com>",
        audience: ["UsGRQJJz5sDfPQDs6bhQ9Oc3hNISuVif"],
      }
    },
  },
  defaults: {
    authorizer: "Authorizer",
  },
  routes: {
    ...
  }
});
They generate the same CloudFormation, and when exported, have the same export name.
@Sam Hulick if u could share ur authorizer definition before and after, I will give it a try on my end.
s
@Frank Yeah, my mistake was not realizing the object key was the name in CFN of the authorizer
So, now when I upgrade production, I can set the proper object name so it matches the 0.69 version
Should save me some hassle
@Frank
Copy code
Error: section 'Outputs' already contains 'ExportsOutputRefRestApiHttpUserPoolAuthorizerF0D1F4E162D79766'
it still thinks this is something new it needs to create. I might be better off renaming it, actually, then just deploying this single stack, then deploy everything else after that
Copy code
Checking deploy status...
prod-microservices-api-base | UPDATE_IN_PROGRESS | AWS::CloudFormation::Stack | prod-microservices-api-base | User Initiated
prod-microservices-api-base | UPDATE_COMPLETE | AWS::CDK::Metadata | SSTMetadata
prod-microservices-api-base | CREATE_IN_PROGRESS | AWS::ApiGatewayV2::Authorizer | RestApiuserPoolAuthorizer4A82D71E
prod-microservices-api-base | CREATE_IN_PROGRESS | AWS::ApiGatewayV2::Authorizer | RestApiuserPoolAuthorizer4A82D71E | Resource creation Initiated
prod-microservices-api-base | CREATE_COMPLETE | AWS::ApiGatewayV2::Authorizer | RestApiuserPoolAuthorizer4A82D71E
prod-microservices-api-base | UPDATE_COMPLETE_CLEANUP_IN_PROGRESS | AWS::CloudFormation::Stack | prod-microservices-api-base
prod-microservices-api-base | DELETE_IN_PROGRESS | AWS::ApiGatewayV2::Authorizer | RestApiHttpUserPoolAuthorizerF0D1F4E1
prod-microservices-api-base | DELETE_FAILED | AWS::ApiGatewayV2::Authorizer | RestApiHttpUserPoolAuthorizerF0D1F4E1 | Cannot delete authorizer 'HttpUserPoolAuthorizer', is referenced in route: POST /admin/coupons/{couponCode}/assign (Service: AmazonApiGatewayV2; Status Code: 409; Error Code: ConflictException; Request ID: 28dbb8db-9e5d-4696-a14a-33c0fc6d91d6; Proxy: null)
POST /admin/coupons/{couponCode}/assign
isn’t even in this stack. how would it know about it? I can see api-base retained the old HttpUserPoolAuthorizer output. the description says
Output added by SST b/c exported value still used in prod-microservices-api-misc, prod-microservices-api-media, prod-microservices-api-files, prod-microservices-api-users, prod-microservices-api-reels
IMO, SST should abstract this 100% away from the developer. it really doesn’t matter what the authorizer is named, at the end of the day. so the object property could just be the type of authorizer (user pool, JWT, etc) and the name is internally generated based on that, and never changes
f
Yeah that should cover most cases.. but in some cases, u could technically create multiple authorizers.
s
hmm. then maybe:
Copy code
authorizers: [{type: 'user_pool', ... }, {type: 'iam', ...}]
f
u can technically have multiple JWT authorizers
s
right. and with the array model above, SST would just decide what to name the resources in CFN
I mean, I dunno how SST/CDK works under the hood, so maybe that wouldn’t work
my project deployed ok this time. unfortunately there’s no set of steps I could give you.. I deployed api-base, got the error above about deleting an authorizer. but then I just ignored that and went ahead & deployed the full set of stacks and it ran fine because the new authorizer was created during the previous failed deploy of api-base. 🤷‍♂️
f
Yeah, could you share what ur authorizer definition was like b4 and after? We should definitely be able to make the underlying CFN resource not change.
s
sure, one sec
1.0:
Copy code
authorizers: {
        userPoolAuthorizer: {
          type: 'user_pool',
          userPool: {
            id: props.cognitoAuth.cdk.userPool.userPoolId,
            clientIds: [props.cognitoAuth.cdk.userPoolClient.userPoolClientId],
          },
        },
      },
      defaults: {
        authorizer: 'userPoolAuthorizer',
      },
0.69:
Copy code
defaultAuthorizationType: sst.ApiAuthorizationType.JWT,
      defaultAuthorizer: new HttpUserPoolAuthorizer(
        'HttpUserPoolAuthorizer',
        props.cognitoAuth.cognitoUserPool!,
        {
          userPoolClients: [props.cognitoAuth.cognitoUserPoolClient!],
        }
      ),
f
Thanks Sam. Yeah, CDK tries to auto-generate the resource ids by default, and if that changes, the underlying CFN resource will end up recreated. We tried to test every constructs to ensure the resource ids are not changed after the update.
Lemme try out ur setup. And see if it’s a case we might’ve missed.
s
I tried
authorizers.HttpUserPoolAuthorizer
and it didn’t work.. so it needed a new name. oh, also I ran into a similar naming issue with an EventBus target
so I had to rename the Lambda function
very odd
f
Just gave this a try, if
userPoolAuthorizer
were named
HttpUserPoolAuthorizer
, the resource id would’ve been the same. And the export name would’ve been the same.
My bad.. we should’ve made that more clear/explicit in the migration doc.
Oh sorry, misread what u said. U tried that 🤔
s
@Frank no worries, all is well! just took a bit of fighting with it