Hi, I work on (part) of the CDK at the moment. If you've found bugs, we'd love to hear about them with an appropriate reproduction over on github[0].
Thus ends my corp-speak. The following is my opinion alone:
The thing that is hard for a lot of people to understand, it feels like, is that the CDK is both a library (nee runtime) and CI system in one. The runtime produces, at the end of the day, a CloudFormation template that gets shoved into the right places. The CDK happens to make generating those easier.
One of the core issues with working with CloudFormation is that it's limited in what the services support it doing. Services introduced before CloudFormation was really launched have the worst, but it wasn't until 2015 or so that most services really had "OK" support for CFN. CloudFormation is also brittle, and this causes a lot of headaches.
CloudFormation can't handle serial operations that require "create & permute" sequences -- where two things have to be set up in order, then glued together later after some kind of configuration. The way the CDK does this is by deploying lambdas that get invoked after your stack is shipped out that make the relevant API calls. Terraform does this by having the code that Terraform runs make the API call. The difference here gets to be that the CDK can synthesize a change long before it is actually effected, allowing for things like second order permutations. Terraform does everything in-situ, standing up infrastructure and taking the place of both the CDK and CloudFormation.
This has upsides and downsides on both, but a large upside (IMO, again) of the CDK approach is that you can code-wise validate certain things ahead of time before they're deployed, whereas with Terraform it's a little harder. Terraform's big upside is that it handles things that are Hard to do with CloudFormation alone by letting you figure out how to actually create/destroy that bit of infrastructure and hook up the relevant parts as one action in one codebase, rather than having to write Lambda handlers (the CDK calls these handlers "Custom Resource", which are different from Constructs) that get deployed and called when you need to setup/teardown/change the relevant parts.
Both Terraform and the CDK are opaque wrappers around AWS as a whole, the difference being that Terraform wrote their own DSL to describe things that gets then attached to their own SDK (which appears to be JS?) with varying levels of integration, whereas the CDK allows you to use whatever language you're already using to build the primary structure of your application, but where you have fully atomic (not just rollback-able) changes via CloudFormation.
[0]github.com/aws/aws-cdk/issues/new