20200920: cloudctl, Testing, and YAML Thoughts

I added tests to ensure Stack.Deploy() is covered. I developed the mockDeployer struct to implement stack.Deployer. I want to ensure that errors and responses from Deployer are handled correctly. From my limited research, I haven't seen many mocks in go packages. I'm unsure why this is. Maybe it's too complicated and using the concrete value is enough? Either case, I added mockDeployer.Verify() so it could report errors when methods were not called.

I'll probably learn why the community does/doesn't follow this behavior in time. For now, the mocks and tests make me feel warm and fuzzy inside. I'm sure I'll eat my own words later.

Oh, I made a similar mock in the cfn package. It's likely a little too complicated. It uses maps and consts to keep track of method calls. Just read the code, you'll see. I spent a lot of effort on it yesterday, but I kept going because I wanted to see where it lead me. I'll let another feature force me to change it.

Finally, I'll add that the aws-sdk-go library's cloudformation API is insanely large. Implementing cloudformationiface in tests is unwieldy. Also, why doesn't cloudformation have an CreateOrUpdate function. awscli has the deploy subcommand, but the go api doesn't have it. Why.

For next time

I want to look at YAML usage for cloutctl. I like that YAML is simple. But I hate that YAML can become complicated. I'll still choose YAML as a format, even with it's flaws. But I hope to define a tight interface into cloudctl with YAML. This keeps learning the tool easy. And in time, I could write validations on top of YAML to ease writing it. I've always hated tools that didn't have an easy way to validate YAML.

After working with tools like salt and ansible, there are a few things off the top of my head that I want/don't want:

  • I don't want to manage very large YAML files. At work, there's a YAML file with 10K lines. There's too many reasons why this exists.
  • I want to have cloudctl semantically validate YAML configuration. For this to work, the set of possible keys should be fairly small and well defined.
  • I do not want Jinja (or go equivalent) in YAML! No! No! No!
  • If YAML becomes complicated and requires logic, I'd rather recommend jsonnet support. Hopefully, I don't have to get to this point.
  • I want to keep away from YAML references and anchors. I've found I have to be careful when using these features of YAML and have noticed with infrastructure tools that I tend to abuse it. For instance, a simple example is creating an anchor for an EC2 AMI image that's used profusely when defining Cloudformation stacks. The anchor allows DRY configuration, so seems like a great first step to manage configuration files. But, changing the anchor will force all Cloudformation stacks to update. If you have a 10k line YAML like I do, then the related Cloudformation stacks will be blasted.