Deploying Updates to Stack Resources
This lab references the code in the aws-connectedcar-dotnet-serverless repository. If you're new to this course, see the introduction for information about setting up your workstation and getting the sample code.
Through the two previous labs we’ve first deployed, and then partially tested the sample code in AWS. In this lab we’ll deploy a second stack to demonstrate how the “full stack” concept works. We’ll then step though making updates to this second stack, performing one update that will work, followed by another update that, by design, will not.
Deploying a Second Stack
We don’t want to change the “Dev” stack that you just deployed in the first lab because you’re still going to be using it. So, instead, what you’re going to do is deploy a second “Test” stack.
Step 1: Set the config.zsh environment variable to “Test”
All you have to do to be ready to deploy an entirely separate stack is change the value of the environment variable in the config.zsh script. Simply replace the “Dev” value, shown below on line 8, with “Test”.
Step 2: Run the deployment scripts again for the second stack
Next, you need to run the three deployment scripts again, in sequence: clean.zsh, build.zsh and deploy.zsh. Once the last script has completed, switch to the AWS console and navigate to the CloudFormation stacks page. The results (with a bit of column tweaking) should look like this, showing a second set of “ConnectedCarTest” stacks above the previously deployed “ConnectedCarDev” stacks:
You’ve now deployed the sample code again, as an entirely separate environment.
Deploying Resource Updates to the Second Stack
Step 3: Edit the Vehicle API resource paths
Now we’ll demonstrate how easy it is to update a resource in a deployed stack. First, in the console, navigate to the Vehicle API for the new “Test” stack, and take note of the REST API resources that it contains. All the endpoints for this API are nested within the /vehicle resource path:
Back in VS Code, open the vehicle.yaml template for the SAM deployment and rename the “/vehicle” path element for the “Create Event”, “Get Events” and “Get Event” Lambda events to “/truck”.
Here’s what this looks like for two of the Lambdas, on lines 99 and 114:
Step 4: Run the deploy.zsh script again to update the second stack
Before we run the deploy.zsh script, let’s take another quick look at the code shown below:
Line 31 has the if statement that checks for the existence of the named stack. So, when we first deploy a stack, the create-stack command gets called on lines 39-48. Now that our stack already exists, the update-stack command in the else block on lines 61-75 will execute instead.
Now, open the console and navigate to the CloudFormation stacks page and leave that open. You don’t need to rebuild or upload the Lambdas. You only need to upload the revised templates and call the CloudFormation commands. To do this, just run the deploy.zsh script again. Once the update-stack command for this script executes, you should see the corresponding updates start to happen in the console:
When the stack update is complete, and while still in the console, you can click on the “ConnectedCarTest-VehicleApiStack” and see the actions performed in the “Events” tab. In this case, you should see the underlying API Gateway component parts, such as the API events and the API event permissions get deleted and replaced with new instances:
If you navigate back to the API Gateway service, and once more select the Vehicle API for the “Test” stack, you should see the changes you’ve just deployed reflected in the resource paths. The API endpoints should now be nested within the “/truck” path, as shown below:
Dealing with Immutable Resource Properties
As we’ve noted previously, there are some resource properties can’t be updated after they’ve been deployed. These properties are flagged in the CloudFormation documentation as modifiable only through “replacement”.
For example, the Customer API in the sample code uses a Cognito User Pool for authentication. This user pool has a resource property that specifies whether usernames are case-sensitive or not. The sample code uses the default value (true) for this property, and so doesn’t explicitly set this resource property in the services.yaml template. What we’ll do now is add this resource property to the template with a value of false, to demonstrate what happens when we try to deploy an update to an immutable resource property.
Step 5: Add the UsernameConfiguration property to the UserPool resource
Open the services.yaml template for the SAM deployment, and then add these elements to the “UserPool” resource properties:
UsernameConfiguration:
CaseSensitive: false
The result should look like this, as shown below, on lines 33-34:
Step 6: Run the deploy.zsh script to update the second stack again
Once more, open the console to see the CloudFormation stacks, and in VS Code run the deploy.zsh script. Watching in the terminal, you should eventually see the stack update fail, showing this result:
If you turn to the CloudFormation stacks in the console, you should see errors in red, like this:
If you click on the “ConnectedCarTest-ServiceStack” and look at the events, you should see the root cause of the deployment error:
Looking at the events in the console shown above, the bottom-most (and earliest) event indicates that the UserPool update is in progress. The next event (above it) then shows that the update has failed because “Updates are not allowed for property - UsernameConfiguration”.
So what’s happened with this deployment? We’ve attempted to update a resource property that can’t be changed once created. As expected, CloudFormation halted the stack update once it encountered this error, and then rolled back the change. Although the stack looks like it’s in an error state, that’s not actually the case. The stack update is in an error state, but the stack itself has been rolled back to its previous configuration. The error messages displayed for the stack in the console will remain until another update is made with statuses that supersede the failed update.
Deleting the Second Stack
Having finished the updates in this lab, we can also demonstrate how easily a stack can be torn down.
Step 7: Delete the second stack from the console
First, in the console, select the “ConnectedCarTest” parent stack, as shown below:
Then click the “Delete” button at the top of the page. At this point you’ll see a warning dialog box, like this:
Click the “Delete” button on this dialog box, and the deletion process will start:
After a few minutes, the parent and nested child stacks should all be gone, leaving you with just the “ConnectedCarDev” stacks:
Step 8: Set the config.zsh environment variable back to “Dev”
To avoid confusion going forward, in the config.zsh script shown below, set the value of the environment variable on line 8 back to “Dev”.
Step 9: Discard the changes to the services.yaml template in VS Code
You should also undo the changes you’ve made to the services.yaml template. To do this, go to VS Code and navigate to the source control view. Then select the services.yaml file under “changes”, as shown below:
With the file selected, click the circular arrow icon (and confirm in the popup dialog) to discard the changes.