federalies / squals

☁️🌦💨a SQUALS movin' in....and the thunder rolls
http://squals.federali.es
MIT License
1 stars 2 forks source link

Output values being referenceable #4

Closed ericdmoore closed 5 years ago

ericdmoore commented 5 years ago

Often you need to make an S3 Bucket - reference that implied domain name as an origin for CDN - and then repeatedly - setup the domain from the CDN into a Route53 A or CNAME record... this is hard to do right now...

Think through the architecture so that this very normal use case becomes obvious...

Maybe by nesting during declaration in a recipe or component show the hierarchy which would then be flattened when serialized into the template...

ericdmoore commented 5 years ago

What if it was like

route53().CNAME({
  ref: cloudFrontCDN().origins[
      S3Bucket().websiteURL
  ]
})

or just as an incredibly ridiculous example....

<Route53CName>
  <Cloudfront comment="testing this CDN" web=true root="index.html>
      <S3BucketWebsite name="someBucket">
      </S3BucketWebsite>
  </Cloudfront>
</Route53CName>

or maybe the nesting is terrible and complicates the idea of each resource really being created.

ericdmoore commented 5 years ago

The real issue is there is a conceptual DAG running through the resources (or modeled objects) which are only partially defined at the time of declaration - and they become full resources at run-time.

ericdmoore commented 5 years ago

Why is this important?

Shipping software as a declared stack is an enticing pattern. You can see the clean borders of "installed" packages (less in a language sense of the word - "package" -- but more in most broad sense of a collection of resources that accomplish a purpose) and see how to update/upgrade & delete them too.

AWS-CDK is trying to solve this too because the cloudformation process right now is a bit overwhelming. I am less excited about turning it into an imperative programming model - and more excited about using creating partials/components/ etc that are exportable/leverageable/shareable by and to other systems. and it seems painfully obvious to me to use the new ESM import/export patterns to accomplish this.

ericdmoore commented 5 years ago

Or, for example maybe S3Bucket() would return an object with properties + attributes in the cloudformation sense of those words - where attributes return a function - to be called later? or perhaps its a Promise resolved ...later?

ericdmoore commented 5 years ago

So far it is easiest to add getters to each class - which does keep it more imperative. so its more like:

const s = new S3Bucket()
console.log(s.DomainName()) 

and actually since the domain does not exist until template is deployed... the s.DomainName() is actually a helper function assuming the property is being referenced...

so it returns { 'Fn::GetAtt': [this.logicalName, 'Arn'] }

ericdmoore commented 5 years ago

This is roughly addressed at least by commit:37ea11fc89daa4d683f529c6405874b97b9f9c41

but there is a greater question of how to create a functional pattern matching on the various types you might want to generate a new template from... (opening a new issue to track that one)