Skip to content

Commit a2a5352

Browse files
authored
Add nuance to outsource-bottom-up (#311)
Previously the outsource-bottom-up.md guidance was tilted strongly towards promoting cloud functions at the expense of any other compute model, whereas the CCoE policy is more relaxed. The previous wording ignores difficulties inherent in the cloud function model which are worth expanding on so that the reasoning behind the recommendations is clearer. Addresses #48, although whether it fixes it is up for debate.
1 parent 811d685 commit a2a5352

File tree

2 files changed

+54
-22
lines changed

2 files changed

+54
-22
lines changed

β€Žpatterns/outsource-bottom-up.mdβ€Ž

Lines changed: 49 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,12 @@
33
- [Outsource bottom up](#outsource-bottom-up)
44
- [Context](#context)
55
- [The pattern](#the-pattern)
6-
- [Benefits](#benefits)
6+
- [Benefits](#benefits)
7+
- [Tradeoffs](#tradeoffs)
78
- [Details](#details)
8-
- [Cloud native vs cloud agnostic](#cloud-native-vs-cloud-agnostic)
9+
- [Containers vs cloud functions](#containers-vs-cloud-functions)
10+
- [Data persistence](#data-persistence)
11+
- [Certificates](#certificates)
912
- [Caveats](#caveats)
1013

1114
## Context
@@ -19,35 +22,64 @@
1922

2023
Use managed services where available and appropriate. The aim is to reduce operational burden by handing responsibility to the cloud provider. They have made a business from doing this better than most organisations can.
2124

22-
## Benefits
25+
### Benefits
2326

24-
- Reduced effort in building the "infrastructure" makes more time to build business valuable functionality.
27+
- Reduced effort in building the "infrastructure" makes more time to build valuable business functionality.
2528
- Reduced operational maintenance overhead.
2629
- Improved reliability.
2730
- Improved security.
2831

32+
### Tradeoffs
33+
34+
- Vendor lock-in
35+
- Reduced technical choice
36+
- New platforms to learn
37+
- Less familiar development process
38+
39+
Our bet is that the benefits outweigh the tradeoffs. On a spectrum between self-managed and entirely vendor-managed, solutions with more vendor management will tend to lock you in more, and make any future platform change harder. In return, we hope for a smaller solution overall, and getting new platform features faster. Similarly the reduced technical choice in language runtimes, data infrastructure, or observability is compensated for by the support levels that the vendor-supplied options enjoy.
40+
41+
Sometimes we have a technical or legislative need to be closer to the self-managed end of the spectrum, and sometimes the ways of working necessary to use cloud products do not align with other engineering requirements, but our first instinct should be to offload responsibility for as much as possible to the vendor.
42+
43+
Some cloud-native choices inevitably imply specialising our solution for that one technology, which could create a degree of vendor lock-in. For instance, for a particular use case AWS Lambda may allow you to deliver and operate far more cheaply than Kubernetes, but would require work to re-engineer if moving to a different cloud provider.
44+
45+
You need to understand and be able to justify a choice that creates vendor lock-in. If the benefits of vendor lock-in outweigh the pain of being locked in, then being locked in is a good thing. Similarly, when looking at the other side of the coin bear in mind that *any* migration between providers, whether from vendor-specific technology or generic, will be expensive because - at the very least - of data locality, access management, and uptime considerations.
46+
47+
The choice is between investing time early to build in mobility and deferring that effort (quite possibly forever) to focus on things which deliver more value to the organisation, but following the principle that nothing untested can be assumed to work, engineering principles dictate that you should have a plan to continue to assure that mobility as the project evolves. If mobility is a required feature, that feature must be tested.
48+
2949
## Details
3050

31-
- Prefer software as a service (SaaS, e.g. Splunk, Jira), then serverless platform as a service (PaaS, e.g. Amazon DynamoDB, AWS Lambda), then infrastructure as a service (IaaS, e.g. cloud VMs).
32-
- For compute, prefer functions as a service (e.g. AWS Lambda), then serverless containers (e.g. GKE, AWS Fargate), then VM based deployments (e.g. AWS EKS, AWS ECS on EC2).
33-
- TO DO: close discussion about whether containers are still preferable in some use-cases
34-
- For data persistence prefer (where there are no other differentiating factors) pay per request options (e.g. Amazon DynamoDB, S3) to pay per time choices (e.g. Amazon Aurora or RDS).
35-
- In general, prefer solutions which do not involve managing VMs if possible, and ideally where there is no explicit configuration of a network (e.g. subnets, internet gateways, NAT gateways) — compare AWS Lambda which needs no network with AWS Fargate which does.
36-
- Where possible, outsource the management (including renewal) of certificates (e.g. via [AWS Certificate Manager](https://aws.amazon.com/certificate-manager/))
37-
- Where that isn't possible, still prefer outsourcing the management of alerting for certificate expiry (see [observability](../practices/observability.md))
51+
Always prefer software as a service (SaaS, e.g. Splunk, Jira), then serverless platform as a service (PaaS, e.g. Amazon DynamoDB, AWS Lambda, Texas, AWS Fargate), then infrastructure as a service (IaaS, e.g. cloud VMs). Cloud VMs are the least flexible option available to us, so should only be used if no other option can be chosen.
52+
53+
Similarly you should prefer solutions which do not require you to manage a network configuration.
54+
55+
### Containers vs cloud functions
56+
57+
If you have a choice as to whether to use functions as a service or a container platform for a part of your implementation, you should consider:
58+
59+
- Are you migrating an existing service, or implementing something new? It may be easier to design a new service on cloud functions and cloud services than on a container platform. Migrating an existing service may be easier if first moved to containers, then having appropriate parts extracted to cloud functions at a later date.
60+
- Is there a software framework particularly well suited to your problem that better fits containers, or to cloud functions? For instance, you may prefer the Django admin interface to having to build your own: this would be better suited to a container platform than on AWS Lambda.
61+
- Implementations based on cloud functions can be harder to test, because you might not be able to instantiate service dependencies locally. Is that important for your use case? Do you have a good developer testing story otherwise?
62+
- Is your implementation primarily plumbing between other services already in the cloud, with little logic of its own? Is it primarily asynchronous? A "yes" to either of these would point in the direction of cloud functions.
63+
- Do you have specific language or runtime version requirements? While these can usually be accommodated on cloud function platforms, there is additional work if your needs do not align with the platform-supplied runtimes. You may find that this erases any advantage to cloud functions over containers.
64+
65+
### Data persistence
66+
67+
For data persistence, where there are no other differentiating factors, prefer pay per request options (e.g. Amazon DynamoDB, S3) over pay per time choices (e.g. Amazon Aurora or RDS).
68+
69+
Bear in mind that for higher-throughput applications where the usage would never scale to zero, or where cold start delays would be problematic, the difference between an autoscaling pay-per-time choice and serverless pay-per-request model may tilt in the other direction. The correct choice will depend on the differentiating factors of your specific application.
70+
71+
A more fundamental principle is that you should never send a document store to do a relational job. Don't pick a NoSQL implementation when you need an RDBMS just because of the payment model: any savings you might expect from the payment model will result in a more expensive, slower, and more painful development experience.
3872

39-
## Cloud native vs cloud agnostic
73+
### Certificates
4074

41-
A closely related, but subtly distinct consideration is whether to prefer cloud native (serverless) technologies or cloud agnostic / generic ones. Cloud native choices inevitably imply specialising our solution for that one technology, which could create a degree of vendor lock in.
75+
Where possible, outsource the management (including renewal) of certificates (e.g. via [AWS Certificate Manager](https://aws.amazon.com/certificate-manager/))
4276

43-
- Understand and be able to justify vendor lock in.
44-
- If the benefits of vendor lock in outweigh the pain of being locked in, then being locked in is a good thing.
45-
- e.g. for a particular use case AWS Lambda may allow you to deliver and operate far more cheaply than Kubernetes, but would require work to re-engineer if moving to a different cloud provider.
46-
- The choice is between investing time early to build in mobility and deferring that effort (quite possibly forever) to focus on things which deliver more value to the organisation.
77+
Where that isn't possible, still prefer outsourcing the management of alerting for certificate expiry (see [observability](../practices/observability.md))
4778

4879
## Caveats
4980

5081
- By outsourcing responsibility you are also relinquishing some control.
5182
- Performance tuning can be needed to achieve reliable β€œflat” response times both during very quiet and very busy periods.
5283
- Special efforts may be needed to ensure services are "kept warm" at quiet times.
5384
- At busy times, throttling or buffering throughput may be needed to avoid overwhelming any related systems which do not scale as elastically.
85+
- Do not assume that services calling yours will throttle or buffer. Build in load shedding and rate limiting to protect your own service where needed. While we aim to be good neighbours of our upstream APIs, failing gracefully in response to excess traffic is your responsibility.

β€Žpractices/security.mdβ€Ž

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -142,17 +142,17 @@ The remainder of this page gives more detailed and specific recommendations to b
142142
<details><summary>Example IAM policy fragment to prevent unencrypted RDS databases (click to expand)</summary>
143143

144144
```yaml
145-
{​​​​​​​​
145+
{
146146
"Sid": "",
147147
"Effect": "Deny",
148148
"Action": "rds:CreateDBInstance",
149149
"Resource": "*",
150-
"Condition": {​​​​​​​​
151-
"Bool": {​​​​​​​​
150+
"Condition": {
151+
"Bool": {
152152
"rds:StorageEncrypted": "false"
153153
}
154-
}​​​​​​​​
155-
}​​​​​​​​
154+
}
155+
}
156156
```
157157

158158
</details>

0 commit comments

Comments
Β (0)