AWS is the core infrastructure resource that we use at my work and we're using it to build our platform as a microservices architecture. There are lots of interesting features provided by AWS and one of the ones we use literally every day is CloudFormation.

All of our individual microservices use CloudFormation templates to launch their necessary resources. I am a fan of these single, cohesive files that bind everything together - it's sort of a "design scaffold" in my mind that we then put our code into. As much as possible, our team tries to keep things contained in these files.

Another cool resource that I was recently introduced to is Swagger (a.k.a. OpenAPI but "Swagger" is just such a better name in my humble opinion). Swagger is essentially a uniformed way to define an API in a single file. Having this stand-alone file is pretty cool because it can then be used in a bunch of different places (e.g. generating documentation, building tests, etc.) outside of strictly constructing the production API.

AWS pretty niftily supports using a Swagger definition to create your API - basically you replace the AWS::ApiGateway::Resource and AWS::ApiGateway::Method resources in your CloudFormation template file with Swagger which is pretty cool.

Sort of.

Now in our case, because we're building microservices we're constantly launching and tearing down individual resource stacks so important resource references (e.g. Lambda ARNs) are changing frequently.

This poses a problem for the two options available in AWS for including Swagger in your template.

Option 1: in-line where the Swagger file contents are directly included in the Body field of the AWS::ApiGateway::RestApi template resource pros: the "Ref' statements can be used to catch dynamic ARN/resource references, flexibility is maintained in between stack launches/teardowns cons: the Swagger contents can't be dropped anywhere else since they're hard-coded into the template, the benefits of an independent Swagger file are lost

where the Swagger file contents are directly included in the field of the template resource Option 2: external S3 file where the Swagger file is stored in S3 and referenced through the BodyS3Location field on AWS::ApiGateway::RestApi pros: the Swagger file is separate, this is ideal for sharing and using in other services cons: the ARN references must be hard-coded in the Swagger file which assumes those resources are permanently available

where the Swagger file is stored in S3 and referenced through the field on

Neither option is particularly good since they sort of cut off the left arm to make the right arm stronger or vice versa. The current workaround I've implemented is to provide a small Python script to insert the Swagger definition. Basically, it takes the CloudFormation template file contents and inserts the Swagger JSON file contents into the Body field at the build stage of our CI pipeline.

It's not an ideal solution but hopefully AWS provides something better soon!