Reputation: 361
As per the CDK "Best Practices" documentation, we should "model all production stages in code".
In the CDK, you can, and should, build that configuration right into your source code. Create a stack for your production environment, and a separate one for each of your other stages, and put the configuration values for each right there in the code.
I got recently reminded of that best practice and read some more on the non-deterministic results you get if you don't abide by it.
For an environment that includes dev
, test
and prod
(for simplicity) this seems doable and combined with AWS Pipeline sounds like a great idea to run deployments (code driven CI/CD). A commit in the code will automatically result in a re-deploy and changes in the environment as necessary. Great.
However where things seem to be a little more complicated is when prod
is really 100s of different tenant environments. So they all "look" the same in terms of the resources they have, but there are differences in, say the network subnets allocations they each use, the vanity name for the access point, etc...
If we want to stick to the deterministic approach referred to above, what is the recommended approach ?
cdk.json
and cdk.context.json
and we just update those branches if the deployment needs to change (for instance a new ECR image version used by Lambda for a specific set of tenants).git rebase
from a common ancestor ?cdk.json
and cdk.context.json
(i.e. tenant1.cdk.json
, tenant2.cdk.json
, etc.) ? Seems rather ugly...Any other suggestions ? Am I missing the point. ?
Or should we somewhat ignore the anti-pattern and introduce more "lookup" and conditional behavior in the code ?
Upvotes: 4
Views: 1535
Reputation: 1781
This is a very interesting question, and one that I also have explored.
NOTE: I am not a pro at this, take everything below with a grain of salt.
As far as I can see, there are two approaches.
I believe StackSets were designed exactly for this purpose, and supposedly they work well.
The only problem is there is no good CDK support for it. There are several issues in the CDK repo discussing this.
There is an RFC for getting the support for StackSets. Sooner or later it will make it into CDK, just not there yet at the time of writing this.
Alternatively, just like with dev
, test
and prod
stages you may just have multiple prod
stages.
Each prod stage may it's own configuration that the stack class gets instantiated with. You can pass any config you want to the stack and use it inside the stack for configuring services, capacity and so on.
We use this approach right now with a small number of production deployments. Essentially, we just have an array of stack configs, that we iterate over in the CodePipeline and deploy stages in parallel.
This is infra-as-code, right? Let's use the full benefits of a real programming language!
You can also keep this config list externally (e.g. in a database), and then fetch the config, and instantiate the stack classes. E.g. you can fetch the config as the first step in the pipeline and dump it as JSON to disk, then in the stack app.ts
read the JSON config and creates an array of stack instances.
Cons: I think there is an arbitrary limit of how many stages you can have per pipeline (or phase?), and it's not very large.
Upvotes: 2