create-stack and update-stack are thin API calls: the first fails if the stack exists, the second if it does not, or if nothing changed. deploy is a CLI command that creates a change set (Change Sets and Policies), executes it and waits, whether the stack exists or not, and treats "no changes" as success:
cd ~/v5-ch7/booknest/infra
aws cloudformation create-stack --stack-name booknest-catalog \
--template-body file://catalog.yaml --output text --query StackId | cut -d/ -f1-2
aws cloudformation wait stack-create-complete --stack-name booknest-catalog
aws cloudformation create-stack --stack-name booknest-catalog \
--template-body file://catalog.yaml 2>&1 | fold -s -w 90
aws cloudformation update-stack --stack-name booknest-catalog \
--template-body file://catalog.yaml 2>&1 | fold -s -w 90
aws cloudformation deploy --stack-name booknest-catalog --template-file catalog.yamlarn:aws:cloudformation:us-east-1:000000000000:stack/booknest-catalog aws: [ERROR]: An error occurred (AlreadyExistsException) when calling the CreateStack operation: Stack [booknest-catalog] already exists aws: [ERROR]: An error occurred (ValidationError) when calling the UpdateStack operation: No updates are to be performed. Waiting for changeset to be created.. No changes to deploy. Stack booknest-catalog is up to date
deploy also differs in its arguments: --template-file takes a local path where the others take --template-body file://... or --template-url, and --parameter-overrides K=V replaces the verbose --parameters ParameterKey=K,ParameterValue=V. --fail-on-empty-changeset makes "no changes" an error again, and --no-execute-changeset stops at the preview.
Use deploy in scripts and pipelines: it is idempotent, and parameters you leave out keep their values. Both accept --capabilities (Fn::ForEach), --tags and --role-arn (IAM for CloudFormation). A template over 51,200 bytes must go through S3 24 : deploy --s3-bucket uploads it for you. Newer CLI releases also accept --deployment-config Mode=EXPRESS on the low-level commands, which finishes an operation once resources are configured instead of waiting until they are ready to serve traffic.