The layers of AWSCDK leads to a lot of brittleness, and that was a huge turn-off for us. I like the thought of building systems in a functional way but the tooling just isn't there yet. I haven't dived too deep into Terraform CDK yet, and Pulumi just had too many problems.
I am finding the same. Even a relatively simple deployment built on CDK has no end to issues and headaches, ranging from rollbacks that don't completely roll back to a previous state, dangling resources that aren't cleaned up properly, and the issues go on and on. This is mainly due to CDK depending on cloudformation which is, in my most humble of opinions, a non-starter for starting up anything more complex than a single ec2 instance.
Had we built this out in terraform, state cleanup and tracking would have been more robust, the ability to retry resource creation would have been more stable, the project overall would have been much more of a pleasure to use. The functional/declarative aspect of terraform in relation to cloudformation is so much more polished.
Crossplane, on the other hand, does better with the Terrajet codegen, and all the infra drifts are a part of the reconciliation cycle, which is very handy on simpler deployments but doesn't work with more complex ones due to excessive drift polling model.
1. both pulumi and crossplane just wraps the Terraform providers as is on many occasions, and quite poorly. There are a lot of pending issues with the dependency graphs, state refresh and proper state diffs. Although a lot of the most troubling issues had been resolved, it's still a mine field run.
2. Both TFCDK and dagger.io can be used for multistage TF deployments, although I prefer dagger myself...
Terraform has a major state management design flaw that had been ignored by hashicorp to force TFE upsales. It's impossible to perform multi stage deployments with a single `terraform apply`. You have to manually identify the deplyoment targets for every stage, terraform providers do not support `depends_on` block and they are not a part of the resource dependency resolution graph. i.e. You can't deploy Vault than configure it with the respective provider - terraform will try to perform both deployment and configuration simultaneously and will fail.
3. This is due to strong Sales Opinion that a Single Plan is of a Positive Product Value for Terraform. While in practice it turned out to be False, the actual Product Value of Terraform is in Single Consolidated Infrastructure state, which can be analyzed by the respective static analyzers (infracost, tfsec, checkov, inframap, driftctl etc). And it's a strong pro compared to both Pulumi and Crossplane...
Having a single state is a blessing for large companies with a tight operational schedule - having multiple states with a single lock can cause conflicts quite often, with volatile outcomes. Yet again, an upsale point for TFE.
Even though Terraform "has more providers" you have to be able to support 'em all by yourself, HashiCorp does not provide a Viable Support Plan for the existing Official Terraform providers (on my xp - maybe someone was more lucky).
That's why I'm often saying that DevOps is not a title, it's a methodology... and every DevSecOps guy should be well versed in golang to be able to support, test and extend the respective tools and operators (k8s automation).