There's definitely more reasons. I didn't want to detract too much from the topic of the blog post when I wrote it, since the post is already obscenely long.
Puppet doesn't have native support for a lot of things, which require us to either implement it in puppet's DSL, or in custom ruby, which the upstream won't take. For instance: git, gems, pip, virtualenv, npm, etc. etc..
Puppet doesn't have looping. I'm always told: "Iteration is evil. Puppet is a declarative language and if you're needing to loop you're doing something wrong." But it's simply not true. Looping making things insanely simpler.
Puppet isn't executed in order, even for the same service in the same environment across systems. You have to very diligently manage every require for ordering, and no one does it right. This had lead to systems unable to run first runs really often, which causes problems with autoscaling. I don't enjoy spending my time cleaning this up often.
Puppet's DSL is full of little gotchas that constantly cause issues for developers who aren't very familiar with Puppet.
Half of our team was very familiar with Puppet. If you look at my blog, quite a few of the older posts are about Puppet. I worked on the puppet infrastructure at Wikimedia Foundation for a long time, and released all of the puppet code as open source (they have 60k+ lines of puppet).
I'm a little sad because most of these issues (as I understand your description them) are already fixed or well underway :( It's probably too late for your specific case but I'd like to reply anyway since a lot of this is "conventional wisdom" based on old information. Full disclosure: I'm the product owner for Puppet and before I worked here, I ran it in large-scale production since 2008.
Not quite sure what you mean by 'native support', but gem and pip package providers are built-in. there are high-quality modules for git (puppetlabs-vcsrepo), virtualenv (stankevich-python), npm (puppetlabs-nodejs), etc -- it's a design decision to move much of this into modules and out of core so they can iterate faster.
While the model definitely wants you to describe relationships between resources if you need to send subscribe/refresh messages, there's toggle-able ordering algorithms that will let you run them in manifest order -- I blogged about it here: http://puppetlabs.com/blog/introducing-manifest-ordered-reso...
The parser and evaluator are undergoing a total rewrite to be an expression based grammar, which is explicitly to make better definition around the language and eliminate the gotchas -- https://docs.puppetlabs.com/puppet/3.6/reference/experiments... (this will also be the default on the next semver major)
Native support for things is irrelevant cause you can use modules from forge, and the community is the largest of all other CM tools around, so I hardly believe that you lack something there.
Actually, you can circumvent lack of looping with defined types and calling them with array. In my opinion if you need loops in your infrastructure code you're doing something wrong.
Saddest thing is that from all the people who brag about migrating away from puppet online nobody actually mentioned some of the drawbacks that are REAL and present - and not even discussed in Puppet community - like lack of simple search function vs complexity of exported resources... that means that people are moving away for reasons different then functionality alone...
Another real issue is the slowness of compile process, which happens on the master. But it's OK for "smaller" deployments - like if you don't go above 10-20k nodes.
Puppet doesn't have native support for a lot of things, which require us to either implement it in puppet's DSL, or in custom ruby, which the upstream won't take. For instance: git, gems, pip, virtualenv, npm, etc. etc..
Puppet doesn't have looping. I'm always told: "Iteration is evil. Puppet is a declarative language and if you're needing to loop you're doing something wrong." But it's simply not true. Looping making things insanely simpler.
Puppet isn't executed in order, even for the same service in the same environment across systems. You have to very diligently manage every require for ordering, and no one does it right. This had lead to systems unable to run first runs really often, which causes problems with autoscaling. I don't enjoy spending my time cleaning this up often.
Puppet's DSL is full of little gotchas that constantly cause issues for developers who aren't very familiar with Puppet.
Half of our team was very familiar with Puppet. If you look at my blog, quite a few of the older posts are about Puppet. I worked on the puppet infrastructure at Wikimedia Foundation for a long time, and released all of the puppet code as open source (they have 60k+ lines of puppet).