Create CloudFront deployment target.
Create a deployment to "deploy" the site to CloudFront, or rather, to create a CloudFront distribution for the S3 bucket.
For now the distribution will be served from S3, so the implementation will look for an S3 target and give an error if there is none.
Here are some more notes on serving S3 content via CloudFront but preventing direct public access to the S3 bucket, in case we decide to go that extra step in a future ticket. After more research it seems possible by turning off S3 static site web hosting, in which case CloudFront web hosting should still work. But there are some caveats, namely that S3 configured redirects (routing rules) won't work (or more accurately, will no longer even exist).
AWS documentation: Restricting Access to Amazon S3 Content by Using an Origin Access Identity
Stack Overflow discussion: Clarifications on serving non website S3 bucket via CloudFront as web site
Creation of a CloudFront is now successful if a certificate has been validated, but there's a bit of a chicken-and-egg problem with creating a certificate and that certificate being verified if the registrar is not yet pointing to the correct name servers, which can't be done until the hosted zone is created. See chickens and eggs in AWS S3 CloudFront deployment with Route 53 and ACM.
The best thing to do for now is to throw an error when the certificate is detected as not yet having been validated. This way on first deployment the process can stop after creation of the hosted zone, allowing the user to point the registrar to the hosted zone's name servers. Then running the deployment again (after giving it a little time for the certificate to be validated) will allow it to continue.
Making the AWS SDK exceptions more integrated in will probably make this entire process be more user friendly.
There seem to be ways to restrict S3 content to be viewed only through CloudFront; see Restricting Access to Amazon S3 Content by Using an Origin Access Identity and Restricting Access to Files in Amazon S3 Buckets. These approaches don't work with S3 buckets configured as website endpoints, however. As the first reference says:
If you use an Amazon S3 bucket configured as a website endpoint, you must set it up with CloudFront as a custom origin and you can't use the origin access identity feature described in this topic.
But maybe there is a way (as part of a future improvement) to turn off static website endpoints in S3 but still serve them through CloudFront. The configuration as per the above documentation seems a bit complex, though, with closer coupling between S3 and CloudFront.