I have limited the comparison only between Terraform and Cloudformation because they come under the "orchestration" category. Tools such as Ansible, Chef, SaltStack, Puppet can perform infrastructure management as well but are more so meant for managing the server configuration. Likewise Terraform, Cloudformation too can be used for configuration of servers but are mainly used for spinning up server resources. Let me keep things simple and point out certain aspects from each tool that may help you on zeroing in the appropriate choice.
Hashicorp's language(HashiCorp Configuration Language) is a lot more readable to a someone who has little or no experience with programming. The syntax is quite simple and easy to follow a template in Terraform. Also HCL is designed to accept JSON syntax as well so even if you wish to code with JSON(don't know why one would want to do that) in Terraform there is nothing stopping you from doing so.
In certain scenarios you will find the dynamic nature of Terraform to pick out values appropriately will simplify your cloud deployments considerably. References to variables, attributes of resources is made simple by the syntax Terraform supports. Cloudformation does provide it's own way of variable reference using intrinsic functions which are quite useful too.
The design of Terraform is as such that it is spread out into modules which increases the number of variable definitions you need to make overall. But at the same time this also makes Terraform modules highly reusable, and swapping out resources is simpler to manage because you can have a module file for each cloud resource and drop them into the root directory when you require it to be deployed.
Terraform can provide a detailed summary of the changes that are going to be applied on the existing design which can make things very clear on differentiating the before and after effects of the said changes.
Terraform allows you to access and import existing resources into the template which is huge plus if such a scenario arises. With Terraform the state of all resources is maintained in JSON file stored locally and not with the cloud provider. So if you are working in teams then maintaining a centralised copy of this state file is crucial to avoid duplication of resources. You can take this point into consideration only if AWS is going to be the only provider you will ever work with because Cloudformation as no such concept and allows simultaneous working with the environment.
The monolithic folder structure in Terraform for it's modules can be a bit of hassle to maintain as things keep getting complex.
Cloudformation supports JSON/YAML. For a novice/experienced programmer the language shouldn't be a barrier at all. YAML actually makes the code seem a bit more easier to read and was welcomed by all when AWS initially started it's support.
If you are going to work on AWS only, then Cloudformation offers certain elements such as automatically figuring out dependencies and cross stack referencing. Cloudformation is smart enough to know if a resource has dependencies irrespective of the code flow and takes the appropriate route to reach the desired state of the stack thereby alleviating the idea of you writing code in some sort of a defined flow.
Cloudformation's support for automated continuous deployment by testing of new changes with the infrastructure and subsequent integration to production environments is pretty good.
The concept of modularity doesn't actually exist with Cloudformation. One way to do it is may be having different templates and calling them with a base template. But again how far you can use those templates remains a question because achieving a truly reusable, modular template is not how Cloudformation is designed to work. You will have to make changes to those templates as needed for the configuration.
Cloudformation performs an entire rollback of resources in case of a failed deployment. This can get a bit annoying because you will end up deploying the same resources every time to the point of failure unless you are able to quickly identify the problem. Terraform only marks the failed resource as "tainted" and attempts to re-provision the failed resource on subsequent execution.
Cloudformation can make updates to current state of the infrastructure based on certain events and ensure that the desired state is reached without terminating or stopping the resources of the stack. This is quite a powerful feature if you know exactly how to use it.
In summary I think you can decide based on what features are appealing to you irrespective of what the cons are from these tools. A quick read at their respective documentations without going knee-deep should give a sense of what will work for you. You may want to lean towards Terraform because of it being open source, it's support for all cloud providers and the community being bigger than Cloudformation but if AWS is going to be your platform then choose wisely. Both have evolved as the years have gone by and will continue to do so.