Does anyone else finds AWS and other Amazon services overly complicated?

208 points by damacaner ↗ HN
I think AWS and its signature system is making things more complicated than it should be, like this is a normal signing in process to API:

1. you request client credentials, which is normal.

2. construct request URL, normal.

3. add headers, eh, normal.

4. signature... fuck.

First you need to convert the URL you have from step 2, mash it with headers from step 3, add header keys to signed headers, then sum256 hash the payload and hex encode it.

Then you create a sign, add algorithm, request date time that is formatted with ISO8601 but all special characters stripped apart, add credential scopes, hash the canonical request you created at the first step.

Then, you calculate this abomination: HMAC(HMAC(HMAC(HMAC("AWS4" + kSecret,"20150830"),"us-east-1"),"iam"),"aws4_request")

after that you calculate this: signature = HexEncode(HMAC(derived signing key, string to sign))

after that you create an authorization header and add signature to it: Authorization: AWS4-HMAC-SHA256 Credential=AKIAIHV6HIXXXXXXX/20201022/us-east-1/execute-api/aws4_request, SignedHeaders=host;user-agent;x-amz-access-token;x-amz-date, Signature=5d672d79c15b13162d9279b0855cfba6789a8edb4c82c400e06b5924aEXAMPLE

...I mean what the fuck? I can understand why people choose Azure over AWS for the sake of freaking simplicity just by looking at this sign and request process. It feels overly-complicated. Does anyone feels the same while working with this abomination?

147 comments

[ 3.4 ms ] story [ 62.5 ms ] thread
Lots of APIs do HMAC signing, not really something I get worked up over.

I use AWS and Azure. Each has their advantages and disadvantages. To answer if something seems "overly complicated" I would have to know, compared to what? AWS certainly has lots of complexity, but so does any services with so many features and moving parts and potentially catastrophic misconfigurations and security threats. Compared to managing servers in a rack I prefer AWS.

It hardly matters in practice because nobody does this, they use the AWS SDK.
But there are libraries for this with wrappers; don’t think many people do this manually or are bothered by it.
I did AWS training at the Amazon offices in Seattle for data science. I was blown away by the configuration... I have recompiled linux kernels and configured iptables as a teenager, and this was an entire galaxy of more complexity. It took us 6 hours to the point where some of us had a Jupyter Notebook running. Many people didn't make it though.
Artificial complexity to justify lock-in and artificial salaries.
The microsoft model of "if sysadmins are spending much more time debugging windows, then they put windows first on their CV and gradually management forgets linux exists"
Obviously! Just like devops as a whole. Why do we have this current mess instead of just pushing stuff to heroku?
Because heroku has limitations.
Oracle DBA’s would like to have a word with you in the back alley
Were you doing things the hard way on purpose? It's literally one click to spin up a Jupyter notebook on GCP, arguably less if you use Colab (instant access to shared instances), and I'm sure AWS has a similar service.

https://cloud.google.com/vertex-ai-workbench

So, if I remember right, the endgame was to have an automated ML model running as a service on an AWS instance with SageMaker. Part of that involved having a Jupyter setup installed. Don't remember much past that, though.
Why?

That doesn't make any sense to me. What problems were you running into? Did you need to configure a bunch of super-non-standard stuff or something?

I though its just me who find it overly complicated.

With people who use AWS SDK its all abstracted out. But there is time I just want to send a damn `curl` to download a S3 file and yes, doing the dance in bash isn't easy.

There is time I wrote a Lua plugin for openresty to fetch s3 and. I have to trial and error with lot of debugging. The ordering. the timestamp format...all of that...

It's even worse. We use presigned URLs (from the SDK) and S3 for file uploads. That's one fresh hell you don't want to get involved with. One of those seemed like a good idea at the time things...
May I ask you why? I use and have used both PUT presigned urls and POST signed policies for uploading file to S3 without too many problems, but your remark worries me a bit. Am I missing something?
We get our customers to upload to S3 directly so we don't have to handle their ingress traffic through our infra. Problems involve mostly when the client cocks up as it's near impossible to distinguish between broken files and good ones. This leads to the assumption that the clients have uploaded a file and they haven't.
Do you mean that you cannot synchronously validate the file and return an error to the client? For async validations a lambda on an s3 trigger works well enough. For sync validation I've found you are limited in what you can encode in an upload policy
Can't do that. The clients own the S3 buckets not us.

The whole idea we had was stupid.

You still can use POST policies, they don't need to be defined on the bucket but only signed. But you are limited on what you can check. Other than that, yeah, the approach might not have been adequate.
If you know the file hash beforehand, you can encode that into the signed URL.

But if you’re saying clients will upload the wrong file, then that’s not really AWS’s fault is it?

If you’re saying the file itself is corrupted, I’m not sure how? The upload should fail if the content length is incorrect, and s3 doesn’t make the contents visible unless the upload completes.

It's the eventual consistency nature of the problem. You have to check and you can't guarantee. Don't expect the clients to work properly either. Edge notoriously started uploading zero byte files when already open in MS office a few months back. Also network connections time out, users close browser tabs etc etc.
Ah that's nothing. Simple problem from a high level: static web site on apex domain.

What you should be able to do:

Click click done. Upload files to S3. Point CNAME at AWS.

What you have to do:

Create an S3 bucket and stick the files in it. Create a zone in Route 53 and import your old zone file. Change your nameservers at the registrar. Wait a bit. Go to ACM in the correct region and create a cert. Tell it to add the DNS entries to R53. Wait a bit. Create a CloudFront distribution making sure that you get all the options right which is quite difficult. While that's deploying, copy the IAM policy it generates back to the S3 bucket. Jump back to R53 and add a new A record pointing at the cloudfront distribution alias. Cross fingers and start praying that the whole stack works. If it doesn't spend several hours working out which thing you forgot to click.

What devops culture would have you do:

Play with CloudFormation for 2 days writing oodles of mind numbing YAML and realise that you have to create the ACM cert and CF distribution in a different region to your bucket but that's impossible. Try and work around this with recommended StackSets but realise they are so horrible that they are unusable. Spend an hour googling. Download terraform because everyone is gushing over it. Spend several hours learning the above and writing it in HCL constantly tearing down and creating resources until the whole thing limps along. Eventually realise you need to share this is someone and the thing is stateful so pay Hashicorp for TF Cloud. After the PO is approved with takes 2 weeks, check it in to git, cheer loudly, hand it over to a colleague who has a different version of terraform and then discover about tfenv and terraform upgrades.

I only do this because I'm paid by the hour. I'm not even a cloud or ops guy. I'm an electronics engineer who needs to eat. I eat well due to this mess but I know it's all so so so wrong.

Are you aware of the AWS CDK?

Doing that in Infra as Code shouldn't take two days IMO.

Yes. CDK is just another way of expressing the same things as terraform and cloudfront but using a framework which is opaque. Plus it's slow as fuck, buggy and difficult to debug when it goes wrong.

Every attempt keeps trying to solve the same problems with a new abstraction but the problem is the underlying abstraction not the tools.

This is what worried me when I see the marketing claiming how easy is it run up infra using AWS SAM. It's all great until something goes wrong and you have to peak behind the curtain to the nest of automatically generated Cloudfoundation scripts.
> CDK is just another way of expressing the same things as terraform and cloudfront but using a framework which is opaque.

It also involves writing many, many less lines of code than Cloudformation/Terraform thanks to the excellent abstractions it bundles in. Your example of writing "2 days' worth of YAML" is less than 120 lines of Typescript in CDK. You could even skip that and just npm install the AWS solutions construct for this scenario if you have literally no idea what you're doing: https://docs.aws.amazon.com/solutions/latest/constructs/aws-...

We don’t know typescript. So we’d have to learn that first.
Do you know JavaScript?
Nope!

Edit: not strictly true. I know JavaScript quite well but I wish to have nothing whatsoever to do with it and the ecosystem around it due to a number of reasons I would have to write a whole essay on.

CDK also works with Java or Python.
To be absolutely fair the CDK is non-trivial.

If you know CloudFormation, you do _not_ know the CDK. The CDK is split in 3 versions, ver 1, ver 2 and v2-alpha. Knowing the difference between L1, L2 missing options between the two.

Don't even get me started on docs. Docs in CloudFormation is KING. CDK's docs are a simplification at BEST. Most of the time I have to drop down into CF's docs to see what the actual constraints on a key are.

Given all my complaints, I'm not going back to CloudFormation. It is wayyyyy less code. Separated files. And, it's too hard to do complex stuff in CF. CDK has a lot of nice magic that takes away so much complexity esp dealing with cross region work.

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

>Go to ACM in the correct region and create a cert

Glad you included the "correct region" qualifier. The number of times I've mistakenly created the certificate in my local region, rather than the one designated for CloudFront...

Yep.

Really these days I want to solve the problem and go home, not remember where the poo I stepped in last time I had to solve it was.

to add salt to the wound, there is a certain service you have to use and provision on us-east-1...such as cloudfront...where you already had the same ACM cert in us-east-2.
I prefer log into Hostgator, click cPanel, click File Manager, drag files across. Any day!

Ok I missed: point DNS to Hostgator name servers. Click the button to install lets encrypt.

Yep, I just opload to my FTP from my file browser (thunar), not even cpanel. I use picocms so can't be easier to manage.
You know it's bad when cPanel is a less painful solution :)
AWS is basically a "construct your own custom infrastructure" service and does that well. But if you're not going past a static page, it's not the best service - just go with vercel or netlify or someone similar instead.

The policies, cloudformation, r53 config, cloudfront all have their purpose and a lot of flexibility. But don't pay the complexity price if someone else can wrap it for you in a nice saas.

100% this. A couple times I've considered moving my personal website to AWS, but each time I got lost in the documentation trying to keep all the different moving parts in my head. At the end of the day managing a single VPS running debian+nginx+certbot[1] with a Gandi domain is orders of magnitude simpler.

[1]: I'm probably going to move that to FreeBSD/OpenBSD with OpenBSD's relayd+httpd+acme-client at some point, but the general idea stays the same.

AWS / systems professional here. I’d use something like Netlify for a personal site instead of the complexities and knobs available when using AWS S3 static site options. AWS bare is the equivalent to me of trying to use Linux From Scratch in 2012 for running a bash script in a cronjob when there’s distributions like Ubuntu out there meant to do a lot of the boring and mostly inconsequential stuff for everyone besides the highly regulated. It’s great for educational reasons but learning and productivity are usually diametrically opposed in use cases.
I learned cloudformation in a day. Everyone on HN said use terraforms. Tried to learn terraforms and it made things complicated. Went back to CF.
I'm currently in the middle of converting my team to straight CF instead of CDK/Terraform/Serverless. To me it's needlessly complicated, CF is simple, configurable, importantly it's _declarative_, which is the 'correct' way to approach infra (imho, of course).

Deploying it? `aws cloudformation package -> aws cloudformation deploy`. That's it. No need for third party tooling or other madness.

I think the lack of understanding the fundamentals leads people to picking up tools that abstract the fundamentals away (but then leads to more complex solutions).

The thing is, Terraform is the industry standard, for better or for worse. Much like Helm for Kubernetes (or Kubernetes, for that matter). If you go somewhere else, the expectation is probably that you know how to use those.
I envy you.

I am using a simple S3 bucket to serve image files.

We’re getting close to busting the free tier web traffic limit.

I can’t figure out where, or how, to enter my boss’s credit card so we can start paying for the service.

I’m not kidding. I’ve looked everywhere. Several times. I’ve probably spent two hours on this.

Sounds like you don’t have billing credentials for your iams user.
Hey, is the AWS account you are using inside an organization? If it's then all the billing information should go into the management account. Hope this is the issue and I could help you.
Here's how this is playing out.

* We need a way to serve image files.

* I create an organization account, add an S3 bucket.

* We serve images as our application grows.

* Fast forward a few months, get an email saying, we're at 85% of free-tier limit.

* I invite my boss to the Organization, and make her the financial contact.

* Neither I, nor my boss, have been able to figure out where, or how, to enter a credit card number.

* We continue to get monthly 85% limit emails. Following the link in the email leads nowhere where we could enter the payment info.

* What a completely insane and stupidly opaque UI. Take our money! How?

* Will probably move to a service that's better organized. We're just serving image files, a few hundred per day.

We have both tried and are unable to figure out how to tie payment info to our AWS organization.

Are you logging in with an Administrator credentialed account _in_ the Organization master account?

Did you give your boss a Billing role in IAM, within the Organization master account?

If so, search for the “Billing” service and Payment Methods will be on the side.

If in doubt, use the root account, but do so only sparingly. You can use it to debug admin and billing permissions.

How can you even get started with AWS without entering payment details? I would love to use AWS for personal projects if I could guarantee it will just stop service outright I stead of charging me.
I've done contract work for a couple of large enterprises. It's amazing how many AWS accounts are just floating around out there on a corp credit card that no one knows who added it and when it's going to expire.
I also used an S3 bucket for static files. The setup was way more complicated than I expected, and figuring out how to get usage statistics and understanding the cost structure even more so. In the end I moved from S3 to a CDN, super simple to set up and costs went down from 200 USD per month to 5 USD per month. I hope I'll never have to deal with AWS again.
Ah I see you haven’t spent countless hours looking at the management console cost breakdown because management says “our cloud spending is too high”, to then read the highest cost is your “cost savings plan”.
I created a CloudFormation script specifically to do this (including CloudFront for CDN). Yes, there's reasonable complexity, but it's a trade-off of security and configuration. As others noted, the documentation is good, and this took me a weekend to write including learning CloudFormation from scratch.

https://github.com/lifebeyondfife/simple-static-website

best part about debuging you HCL/CL is when you cannot delete some resource and it won't tell you why besides "is in use".

I created account after account at first and then had hell deleting them entirely. was still easier than figuring out was using a vpc that had nothing visible attached to it

(comment deleted)
> I eat well due to this mess but I know it's all so so so wrong.

That's the point - I do this too. I like the fact that AWS jobs pay well. I'm fair and I always point out to my clients that AWS is expensive and it will cost them more in the long run, and the vendor lock-in is considerable - but they don't care as "everybody is doing it." Well, that's fine with me, I also like to eat well.

I recently created a static site at a zone apex without Route53. Everything else just works, well, as you illustrate.

> Play with CloudFormation for 2 days writing oodles of mind numbing YAML and realise that you have to create the ACM cert and CF distribution in a different region to your bucket but that's impossible.

The discrepancies in cross-region support specifically with ACM drives me nuts.

I noped away from Terraform back in 2019. At the time, the state management component was too immature, and it was a little.. lose with credential security.

You may like Ansible far more if you’d like something a bit more declarative, readable, and with “batteries included.” I have a close friend who is an EE and he finds tools like Ansible much more intuitive and enjoyable than Terraform and CloudFormation.

Every tool has its master.

Use the SDK? Think about what this protects against - it's fair to think you may not need that much protection, but it's hardly pointless.
That is why they give you the SDK - if you choose to not use it, and unnecessarily make your work more difficult - thats on you.

Most people don't build their signatures by themselves - they use the SDK provided.

No, I use the SDK or the CLI tools available for everyone.
You probably want to be using one of the popular libraries to do that.

AWS documentation isn't consistently good, and there are lots of decoys. So, if you wound up in some local minima that made it look like you had to implement the signing and such yourself, try a Web search that includes the name of your chosen programming language.

(A long time ago, I had to implement the AWS client API from scratch, but that's because I was using a fringe language that didn't have such libraries.)

I like your language of decoys and local minima. It's very easy to follow out of date documentation and find yourself wasting time in a cul-de-sac
If you don't use the SDK, how can you judge anything as being "overly complicated"? I mean, I don't know about you, but, last time I checked, signatures, certificates, security and all that stuff IS SUPPOSED to be super complicated because it's a subject with a very high inherent complexity in and of itself. The SDK exists and is well designed to precisely shield you from said complexity. If you deliberately choose not to use it or can't for some reasons then yes... The complexity will be laid bare
HN users routinely try to do things the obtuse way and then complain when its hard. Throw in something about the SDK being spyware or not following the unix philosophy.
> I mean, I don't know about you, but, last time I checked, signatures, certificates, security and all that stuff IS SUPPOSED to be super complicated because it's a subject with a very high inherent complexity in and of itself.

Actually, security is not supposed to be complicated. "Complicated" is the anti-thesis of "secure".

Have you ever tried to import the AWS SDK into a front end client? It's huge. Last time I tried it, it added multi MB of JS to my SPA, so I could do a relatively "simple" call using it. Yuck.

It did not tree shake cleanly with my build system and I eventually ended up just yanking AWS from the stack entirely.

Did you import the entire SDK, or only the SDK for the service you actually needed?
Only way I could figure out was using the core SDK. There was no service-only option that I could find. I just spent 5 minutes looking, just now, to see if another option exists. I got nothing.

So... if it is out there, it's complicated enough I couldn't find my miss-steps then or now.

IAM is the one for me. I can stumble through the basics, but trying to keep everything least privilege adds a layer of pain to everything relatively complex that I try to do.
Absolutely, there's so many services and permissions that getting them to all work together happily can be complex. I work at a company where we have both AWS certified engineers and some very smart people in general, and there's been times when we spend ages trying to figure out why one particular service can't read data from an S3 bucket (or a particular folder in bucket).
Can confirm this was a intense 12 hours of work to get it working properly. Their example and explanation in the docs is also very vague and borderline misleading at points.

Another example is Google cloud run vs elastic container service. Cloud run is dead easy to get up and running. ECS is a mess of confusing terminology and unnecessary complexity. I literally do not care what class of machine you will use to run my container. If I cared that much I would have used a proper EC2 instance.

Have you looked at ECS Fargate? That should manage the instances for you transparently. It’s been around for probably five years or so.
I think I'd rather take the 12 hour hit and get it working on EC2 then paying the ongoing convenience fee charged for Fargate.
Unless your time is free, you have to run a ton of containers to break even, especially because Fargate avoids paying for EC2 capacity which can’t fit a container. It’s certainly possible to save money but my experience has been that people save less than expected once they account for ops time.
(comment deleted)
Yeah this is normally why you'd use the SDK, because its just horrific when you're outside.

However, having said that, compared to FAANG internal tools, its actually not that bad. It's at least vaguely consistent

> compared to FAANG internal tools, its actually not that bad

It's because it is an "internal tool". All services are built on top of aws native.

It's the contrary.

An internal service is really good and then it becomes an AWS service.

I've even been in 2 teams that have tried to do that and one may succeed in a few years.

In my team, all of our services are built on top of AWS.
> However, having said that, compared to FAANG internal tools, its actually not that bad. It's at least vaguely consistent

Actually I find a lot of Amazon's internal tools to be a breeze to use compared to AWS.

Basically all the painful Amazon-specific stuff is done for you so it makes everything very easy.

Some stuff is bad obviously but what we use the most is pretty freaking good.

You HMAC the region so that in case a region is compromised, other regions aren't as well. You HMAC the service so that in case a service is compromised, other services aren't as well, you HMAC the timestamp for obvious reasons (time bound the signature), the outer "aws4_request" HMAC, I'm sure there's a good reason for. Maybe just versioning? Not sure.

Also: All of this is handled in the SDKs. Anyone implementing this themselves either isn't using the right libraries or has a very special use case.

I'm sure there are "reasons" why the HMACs are layered, the question is, does using HMACs actually add useful security properties here, or is this layered HMAC really just a way to generate a cryptographically secure id? If the latter, then can't you just generate that directly rather than needing to gather all of the right information and HMAC it in just the right way?
Sorry, how do you propose to transmit a signature over the wire such that if it were compromised, the blast radius is limited to only the called service within the called region within a finite time window?
Is the signature even necessary? As I said, an opaque bearer token is considerably simpler. Generate as many as you need for whatever services you're running to limit the damage of a leak. Set server-side policies for expiration or whatever else.
This would compromise on security (for this scheme, time window will presumably be longer, many more keys that can be compromised) and would create an explosion of keys for the user to manage, effectively offloading that work to your customers. I don't know that it would present a simpler experience to force your customers to have a different key for every service for every region.

Anyway, this is from the perspective of a large service provider. For side projects or smaller services, yeah simple can be good. But it really depends on your security requirements, threat model, customer requirements, etc.

when a request hits the server authenticating you, it has to recreate the signature. aws doesn’t want to provide those services your raw credential because that makes any aws host a very juicy target. instead, they provide the partially evaluated signature including region and service and then they continue the process. this means that if you compromise an ec2 host, the only credentials you get are usable against ec2. the idea is that if you were able to achieve that, you likely don’t even need those credentials to do worse things to ec2.
> when a request hits the server authenticating you, it has to recreate the signature

Authentication doesn't require signatures, that's my point. They often place the burden of getting the security right on the client.

so you mention bearer tokens in another comment, so i’ll speak to that.

while bearer tokens are simpler, the protection they provide is more limited. for example, a bearer token has no request affinity so if i get your token for service foo from a request you made, i can impersonate you for the lifetime of that token. and it’s much easier to get your token, because it has to live your physical machine to be of any use.

with bearer tokens, the only way to reduce blast radius is to generate more tokens. get a token per-service/region, get a token every 5 minutes, etc. this is possible, but comes at the expense of availability. if the token vendor is down, the impact of the outage is proportional to how frequently and in what situations a caller needs to get a new token.

with signatures and client computation of scoped keys, you’re able to use much longer lived credentials while generating short term credentials only where necessary for that request.

This title could be improved to clarify it's the API signature process OP has an issue with.
Your complaint isn’t about AWS, it’s about the authentication scheme. I find it to be pretty neat, especially when it’s flexible enough to create signed URLs for any method and send them to third parties. We use that as a basis for service-to-service auth. It’s cool and flexible. But overall this complaint seems pretty shallow. You’d just use the client SDKs they publish, or if you want to really go off the beaten path you could just use the signing methods from those SDKs with your own request/response calls.

And if you’re building your own SDK (why?), well there is a lot more complexity down the line once you get past authentication.

> And if you’re building your own SDK (why?)

There are more languages than C++, Go, Java, JavaScript, Kotlin, .NET, Node.js, PHP, Python, Ruby, Rust & Swift.

Of course there are. And there are also unofficial SDKs for many other languages.

But if you’re building a feature to interact with AWS then ignoring the availability of SDKs is stupid. If you want to write your service in brainfuck then go for it, but don’t blame AWS for that decision.

(comment deleted)
When you're outside, it's really horrific, so you'd normally use the SDK. In spite of that, it's actually not all that bad compared to FAANG's internal tools. I think it's at least vaguely consistent
Not remotely. Every aspect of request signing has a purpose, and I appreciate that security is actually a concern at AWS. Plus, signing is implemented as a library almost everywhere you can think of.
Yeah, at least getting used to signings might come useful in the future.
Well, if you bill by the resources used, you really have no incentive to run an operation where building clean and resource-effective applications is easy, or where migrating to another platform is painless.
I mean, Amazon does a pretty good job of helping you write reasonably resource-efficient applications, and I’ve migrated from AWS to GCP and there wasn’t any particular lock-in that one wouldn’t have experienced in moving between a cloud provider and on prem or vice versa. Moreover, as it pertains to this post, AWS provides dozens of high-quality SDKs so you never actually have to know about this stuff. I’ve been using AWS for a decade and I’ve never known about how requests are formed.
My main problem with AWS has always been the console UI being horrendous and inconsistent, the poor documentation and having far too many services.

Also, AWS not having something like Azure's resource groups or GCP's projects and instead telling you to create accounts for different projects and environments, and using AWS Organizations or however they call it sounds like a huge PITA.