This change keeps the lumi prefix on our CLI tools.
As @lukehoban pointed out in person, as soon as we do pulumi/coconut#98,
most people (other than compiler authors themselves) won't actually be
typing the commands. And, furthermore, the commands aren't all that bad.
Eventually I assume we'll want something like `lumi-js`, or
`lumi-js-compiler`, so that binaries are discovered dynamically in a way
that is extensible for future languages. We can tackle this during #98.
Our initial implementation of assets was intentionally naive, because
they were limited to single-file assets. However, it turns out that for
real scenarios (like lambdas), we want to support multi-file assets.
In this change, we introduce the concept of an Archive. An archive is
what the term classically means: a collection of files, addressed as one.
For now, we support three kinds: tarfile archives (*.tar), gzip-compressed
tarfile archives (*.tgz, *.tar), and normal zipfile archives (*.zip).
There is a fair bit of library support for manipulating Archives as a
logical collection of Assets. I've gone to great length to avoid making
copies, however, sometimes it is unavoidable (for example, when sizes
are required in order to emit offsets). This is also complicated by the
fact that the AWS libraries often want seekable streams, if not actual
raw contiguous []byte slices.
This reverts back to the old style of having the resource name as its
first parameter in the generated package. Stylistically, this reads a
little nicer, and also ensures we don't need to rewrite all our existing
samples/test cases, etc.
In a few places, an IDL type will be a pointer, but the resulting
RPC code would, ideally, be the naked type. Namely, in both resource
and asset cases, they are required to be pointers in the IDL (because
they are by-pointer by nature), but the marshaled representations need
not be pointers. This change depointerizes such types in the RPC
unless, of course, they are optional in which case pointers still make
sense. This avoids some annoying dereferencing and is the kind of thing
we want to do sooner before seeing widespread use.
This triggers complicates with local development, due to the way
that Glide vendors dependencies. After we move to distinct repos
for the various provider packages, we can go back to doing this.
Now that the IDL types encode named resources as a first class concept,
there is no need to do the dynamic overriding dance in the AWS provider.
I should have included this in my final "banking" of the IDL changes.
This change includes all of the CIDLC generated code for the AWS
package. Just as we vendor and version the generated gRPC code,
we will do so for these files also. This allows building of the
full packages without needing to run any special tools, in addition
to letting us keep track of generated code deltas over time.
This checkin contains all the non-generated package files. This includes
the package metadata, utility functions like utils/instanceMaps, and the
module layouts (these being a candidate for auto-generation down the road).
In addition, the install script has been updated fo reflect the new layout.
The old TypeScript resource definitions may now go away in favor of
the new IDL and associated generated code. After this change, I will
check in the generated code, so that the repo is self-contained.
This is just a minor stylistic change. Instead of letting the AWS
package imports take the good names, prefer to use the generated IDL
names (since they contain the strongly typed data structures).
Unfortunately, this wasn't a great name. The old one stunk, but the
new one was misleading at best. The thing is, this isn't about performing
an update -- it's about NOT doing an update, depending on its return value.
Further, it's not just previewing the changes, it is actively making a
decision on what to do in response to them. InspectUpdate seems to convey
this and I've unified the InspectUpdate and Update routines to take a
ChangeRequest, instead of UpdateRequest, to help imply the desired behavior.
This change rejects non-pointer optional fields in the IDL. Although
there is no reason this couldn't work, technically speaking, it's almost
always certainly a mistake. Better to issue an error about it; in the
future, we could consider making this a warning.
This "strongly types" the aws.ARN type. In reality, it is simply an
alias for a string at the moment (as this is what it boils down to on
the wire), but this at least gets us some amount of compile-time safety.
This change includes resource IDL definitions for all of AWS API Gateway's
corresponding CloudFormation resource types. There are no actual provider
implementations yet.
This introduces an http.API abstraction to Mantle and implements it
for Kubernetes Fission. (The AWS implementation will come shortly,
but requires a fair bit of API Gateway elbow grease first.)
This lets you invoke a function in response to an API event:
let func = new mantle.func.Function(
(e, ctx, cb => { ... },
);
let api = new mantle.http.API("/hello", "GET", func);
This change renames two provider methods:
* Read becomes Get.
* UpdateImpact becomes PreviewUpdate.
These just read a whole lot nicer than the old names.
This change flattens the Fission metadata property on the Coconut
side so that it is nicer to consume. Due to struct embedding in Go,
we need to perform translation at the serialization boundary anyway,
so the less-usable approach we had before didn't really buy us anything.
The Fission internal data structures reference one another by
name/URI. Coconut needs the graph with dependencies, however, so
we prefer to model things using real object references in these
situations. (This also makes it much nicer to program.) This
changes to fit the Coconut model better; the provider will then
turn around and present names/URIs to the various APIs.
This change introduces an @asset decorator in addition to a Code
asset type. The idea here is that compilers will recognize the
presence of @asset and react by spewing the code as a textual
asset, rather than an AST and/or actually getting compiled into IL.
This change introduces some resource IDL types for the Fission
project (https://github.com/fission/fission), which is a
functions-as-a-service (FaaS) substrate on top of Kubernetes.
It has a single configuration variable,
`kube-fission:config:controller`, which controls the address of
the Fission controller in the target Kubernetes cluster.
Someday, ideally we would rebuild this atop a more general
Kubernetes resource package, and add some sort of discovery of
this controller, to minimize the amount of manual configuration
required and to make it more resilient to self-healing operations.
This is IDL-only. The provider is coming soon.
This introduces a new experimental cross-cloud package, Mantle. This is part
of getting pulumi/coconut#134 up and running.
For now, there isn't much here, except for configuration of the target cloud and
scheduler, plus the ability to create a cross-cloud function. (OK, it's not truly
cross-cloud yet, since we have only implemented AWS Lambdas.)
Mantle is, of course, a placeholder name. Since this is a higher level
abstraction than the unopinionated core primitives, the name mantle corresponds
to the Earth's upper layers (and I thought "Crust" would be a rather odd name).
This change introduces a bunch of new AWS resource types:
* aws:iam/Group
* aws:iam/Policy
* aws:iam/Role
* aws:iam/User
* aws:kms/Key
* aws:lambda/Function
* aws:sqs/Queue
None of the associated resource providers are included; this is
an IDL-only projection of the types, their properties, and the
associated API documentation. Lacking these is blocking me from
making progress on the cross-platform functions project.
It's a little unfortunate to be digging the hole deeper in advance
of pulumi/coconut#133 landing. However, we are laser-focused on the
pulumi/coconut#134 prototype, so for now I'll just keep going.
This change includes a first basic whack at implementing S3 bucket
objects. It leverages the assets infrastructure put in place in the
last commit, supporting uploads from text, files, or arbitrary URIs.
Most of the interesting object properties remain unsupported for now,
but with this we can upload and delete basic S3 objects, sufficient
for a lot of the lambda functions management we need to implement.
This change introduces the basic concept of assets. It is far from
fully featured, however, it is enough to start adding support for various
storage kinds that require access to I/O-backed data (files, etc).
The challenge is that Coconut is deterministic by design, and so you
cannot simply read a file in an ad-hoc manner and present the bytes to
a resource provider. Instead, we will model "assets" as first class
entities whose data source is described to the system in a more declarative
manner, so that the system and resource providers can manage them.
There are three ways to create an asset at the moment:
1. A constant, in-memory string.
2. A path to a file on the local filesystem.
3. A URI, whose scheme is extensible.
Eventually, we want to support byte blobs, but due to our use of a
"JSON-like" type system, this isn't easily expressible just yet.
The URI scheme is extensible in that file://, http://, and https://
are supported "out of the box", but individual providers are free to
recognize their own schemes and support them. For instance, copying
one S3 object to another will be supported simply by passing a URI
with the s3:// protocol in the usual way.
Many utility functions are yet to be written, but this is a start.
This change includes a simple cpuwatch package, as a demonstration of
how easy it can be to add CPU-level monitoring to an existing stack.
It contains a single API, enableAlarm, that takes an instance and
CPU % threshold; if the CPU ever exceeds that threshold for a sustained
period of time (3 consecutive minutes), an email will be generated.
To use this, first simply install the package as usual, e.g.
$ coco pack get cpuwatch
From there, you will need to configure the email address to send to:
$ coco env config <env> cpuwatch:config:emailAddress joe@pulumi.com
And finally, add an import plus call to enableAlarm for all instances:
import * as cpuwatch from "cpuwatch";
..
let instance = new aws.ec2.Instance(...);
cpuwatch.enableAlarm(instance, 90); // email if >90% CPU utilization.
As part of this, I've added the typing projections for the AWS SNS topic
and CloudWatch alarm resource types (but no providers just yet).
This changes the object mapper infrastructure to offer more fine-grained
reporting of errors, and control over verification, during the mapping from
an untyped payload to a typed one. As a result, we can eliminate a bit of
the explicit unmarshaling goo in the AWS providers (but not all of it; I'm
sure there is more we can, and should, be doing here...)
This change adds the ability to specify analyzers in two ways:
1) By listing them in the project file, for example:
analyzers:
- acmecorp/security
- acmecorp/gitflow
2) By explicitly listing them on the CLI, as a "one off":
$ coco deploy <env> \
--analyzer=acmecorp/security \
--analyzer=acmecorp/gitflow
This closes out pulumi/coconut#119.
This change checks that the AMI referenced in an instance provisioning
is valid. If not, the deployment is rejected before even trying. This
is part of pulumi/coconut#115.
This change fixes up a handful of CocoJS runtime issues preventing
it from compiling; we aren't using much of this yet, but I hope to
resurrect it soon (so more legal ECMAScript code can run).
This changes a few naming things:
* Rename "husk" to "environment" (`coco env` for short).
* Rename NutPack/NutIL to CocoPack/CocoIL.
* Rename the primary Nut.yaml/json project file to Coconut.yaml/json.
* Rename the compiled Nutpack.yaml/json file to Cocopack.yaml/json.
* Rename the package asset directory from nutpack/ to .coconut/.
This change refactors the existing property verification logic for
the AWS provider to use the new checking capabilities. Beyond just
checking for required properties, there isn't much here yet. There
is a single check for security group description length that goes
beyond this, mostly for illustration purposes.
This is part of pulumi/coconut#115, although there is clearly more
to do here for something sufficiently snazzy and demoable.
This change adds a new resource.NewUniqueHex API, that simply generates
a unique hex string with the given prefix, with a specific count of
random bytes, and optionally capped to a maximum length.
This is used in the AWS SecurityGroup resource provider to avoid name
collisions, which is especially important during replacements (otherwise
we cannot possibly create a new instance before deleting the old one).
This resolvespulumi/coconut#108.
This change tracks which updates triggered a replacement. This enables
better output and diagnostics. For example, we now colorize those
properties differently in the output. This makes it easier to diagnose
why an unexpected resource might be getting deleted and recreated.
This change, part of pulumi/coconut#105, rearranges support for
resource replacement. The old model didn't properly account for
the cascading updates and possible replacement of dependencies.
Namely, we need to model a replacement as a creation followed by
a deletion, inserted into the overall DAG correctly so that any
resources that must be updated are updated after the creation but
prior to the deletion. This is done by inserting *three* nodes
into the graph per replacement: a physical creation step, a
physical deletion step, and a logical replacement step. The logical
step simply makes it nicer in the output (the plan output shows
a single "replacement" rather than the fine-grained outputs, unless
they are requested with --show-replace-steps). It also makes it
easier to fold all of the edges into a single linchpin node.
As part of this, the update step no longer gets to choose whether
to recreate the resource. Instead, the engine takes care of
orchestrating the replacement through actual create and delete calls.
This change introduces a new RPC function to the provider interface;
in pseudo-code:
UpdateImpact(id ID, t Type, olds PropertyMap, news PropertyMap)
(bool, PropertyMap, error)
Essentially, during the planning phase, we will consult each provider
about the nature of a proposed update. This update includes a set of
old properties and the new ones and, if the resource provider will need
to replace the property as a result of the update, it will return true;
in general, the PropertyMap will eventually contain a list of all
properties that will be modified as a result of the operation (see below).
The planning phase reacts to this by propagating the change to dependent
resources, so that they know that the ID will change (and so that they
can recalculate their own state accordingly, possibly leading to a ripple
effect). This ensures the overall DAG / schedule is ordered correctly.
This change is most of pulumi/coconut#105. The only missing piece
is to generalize replacing the "ID" property with replacing arbitrary
properties; there are hooks in here for this, but until pulumi/coconut#90
is addressed, it doesn't make sense to make much progress on this.
This change adds a requireRegion helper function to the AWS library,
enabling easy fetching of the current region (and/or throwing if the
region hasn't been properly configured).
This change improves the verify command by unifying its package
discovery logic with compile. All libraries are also now verified
before installing, just to catch silly mistakes (compiler bugs, etc).
This also fixes a verification error in the AWS library due to
pulumi/coconut#104, the inability to use `!` on "anything".
For now, we will disable the CocoJS library's ECMAScript runtime
layer, because it's causing some troubles. The details -- and
reenabling it -- are tracked in pulumi/coconut#103.
* for ..of isn't yet supported yet (see pulumi/coconut#88); in its
absence, use a regular for loop so that this library can compile.
* List coconut as a dependency.
* Eliminate some superfluous "\n"s.
* Remove the redundant properties stored on AWS resources.
* Compute array diff lengths properly (+1).
* Display object property changes from null to non-null as
adds; and from non-null to null as deletes.
* Fix a boolean expression from ||s to &&s. (Bone-headed).
This change introduces a new informational message category to the
overall diagnostics infrastructure, and then wires up the resource
provider plugins stdout/stderr streams to it. In particular, a
write to stdout implies an informational message, whereas a write to
stderr implies an error. This is just a very simple and convenient
way for plugins to provide progress reporting; eventually we may
need something more complex, due to parallel evaluation of resource
graphs, however I hope we don't have to deviate too much from this.
This change waits for EC2 instance state changes (to running when
creating, and to terminated when deleting), before proceeding. Note
that we probably want to replace this with custom wait functionality
so that we're entirely in control of the retries, timeouts, logging, etc.
I'll do this soon as part of adding similar waits for security groups.
* Specify MinCount/MaxCount when creating an EC2 instance. These
are required properties on the RunInstances API.
* Only attempt to unmarshal egressArray/ingressArray when non-nil.
* Remember the context object on the instanceProvider.
* Move the moniker and object maps into the shared context object.
* Marshal object monikers as the resource IDs to which they refer,
since monikers are useless on "the other side" of the RPC boundary.
This ensures that, for example, the AWS provider gets IDs it can use.
* Add some paranoia assertions.
This commit includes a basic AWS resource provider. Mostly it is just
scaffolding, however, it also includes prototype implementations for EC2
instance and security group resource creation operations.
* Add a TODO as a reminder to implement number toString formatting.
* Change the Loreley delimiters to something obscure ("<{%" and "%}>")
to avoid conflicting with actual characters we might use in messages.
Also, make the assertions more descriptive should Loreley fail.
* Rip out a debug.PrintStack() in verbose logging.
* Check the underlying pointer's object type for +=, not the pointer type.
This change implements some key ECMAScript runtime helpers, straight from
the specification: https://tc39.github.io/ecma262/. The goal here is to get
a runtime intrinsic for ECMAScript-style toString to work.
This change implements intrinsic function support in the runtime.
The basic idea is to swap out references to MuIL functions with
runtime-implemented functionality, for operations that cannot be
expressed in the MuIL-subset. For example, this change includes
two such cases: 1) a mu.runtime.isFunction(obj) function to check if
the target object is a function; and 2) a
mu.runtime.dynamicInvoke(obj,obj,obj[]) function to dynamically
invoke a target object.
These will be used most immediately to implement ECMAScript toString
functionality in the MuJS runtime library, however it will also come
in handy shortly to implement things like printf (marapongo/mu#86),
string and array functions (marapongo/mu#80), and, eventually, the
ECMAScript-specific operators and behavior (marapongo/mu#61).
This change introduces a MuJS standard library. This will allow us
to support an increasing amount of ECMAScript functionality without
needing to do it in the runtime or the compiler.
The basic idea is as follows.
In the TypeScript compiler, all uses of ECMAScript standard types and
functions get bound to the TypeScript library headers. These headers
are in the node_modules/typescript/lib/ directory, and there is one
per ECMAScript "standard" (lib.d.ts for ECMAScript 5, lib.es2015.d.ts
for ECMAScript 6, lib.es5016.d.ts for ECMAScript 7, and so on). Note
that these libraries are "header only", since the functionality for
these are of course supplied by whatever runtime (V8, Chakra, etc)
actually executes the resulting JavaScript code.
In our case, we have no such luxury. So instead, we intercept these
bindings and transform them into bindings to a MuJS standard library.
This library is just a MuIL library written in MuJS code. Only the
set of operations expressable in basic MuIL can be used to implement
these. In select few cases, we will need runtime intrinsics, but those
will not be specific to MuJS and will go into the basic Mu library and
shared among all MetaMu compilers.
At this point, the MuJS standard library only contains the ECMAScript
Error type, so that we can represent throwing errors in MuJS/MuIL.
This change moves the Mu library files back to the root. Until
marapongo/mu#57 allows us to choose a different index file, via
package.json's "main" attribute, the default module logic won't
work properly with the files underneath src/.
This change eliminates the AWS package's cloudformation.expandTags
functionality. The primary reason is that we haven't yet implemented
string/array intrinsics (see marapongo/mu#80), and so the presence of
this routine was preventing verification of the AWS library. But, it
turns out, the expandTags routine was violating our "zero artistic
license" principle for the foundational cloud packages. Namely, it
was auto-adding the Name=<name> tag, when the name property was set,
capturing an idiomatic AWS resource pattern. Instead of doing that,
we will just project tags in their raw form, and add such conveniences
(possibly) add a higher level in the layer cake.
After a bit more thinking, we will create new SDK packages for each
of the languages we wish to support writing resource providers in.
This is where the RPC goo will live, so I have created a new sdk/
directory, moved the Protobuf/gRPC definitions underneath sdk/proto/,
and put the generated code into sdk/go/ and sdk/js/.
This change:
* Renames the Mu standard library NPM package from "mu" to "@mu/mu".
This reflects the convention that MuPackages published on NPM will,
at least initially, be published under the "@mu" scope. This
indicates that a package is intended to be consumed by Mu programs.
* Adds an NPM peerDependency on the Mu package from the AWS package.
* Adds a Mu dependency on the Mu package from the AWS MuPackage.
This nixes the old *.mu files from the AWS MuPackage (when Mull was a thing),
and the nasty YAML files (when Go templates in YAML was a thing...(?!)). The
TypeScript variants remain, however, which is what we'll use going forward.
This rearranges the library code:
* sdk/... goes away.
* What used to be sdk/javascript/ is now lib/mu/, an actual MuPackage
that provides the base abstractions for all other MuPackages to use.
* lib/aws is the @mu/aws MuPackage that exposes all AWS resources.
* lib/mux is the @mu/x MuPackage that provides cross-cloud abstractions.
A lot of what used to be in lib/mu goes here. In particular, autoscaler,
func, ..., all the "general purpose" abstractions, really.
In the old system, the core runtime/toolset understood that we are targeting
specific cloud providers at a very deep level. In fact, the whole code-generation
phase of the compiler was based on it.
In the new system, this difference is less of a "special" concern, and more of
a general one of mapping MuIL objects to resource providers, and letting *them*
gather up any configuration they need in a more general purpose way.
Therefore, most of this stuff can go. I've merged in a small amount of it to
the mu/x MuPackage, since that has to switch on cloud IaaS and CaaS providers in
order to decide what kind of resources to provision. For example, it has a
mu.x.Cluster stack type that itself provisions a lot of the barebone essential
resources, like a virtual private cloud and its associated networking components.
I suspect *some* knowledge of this will surface again as we implement more
runtime presence (discovery, etc). But for the time being, it's a distraction
getting the core model running. I've retained some of the old AWS code in the
new pkg/resource/providers/aws package, in case I want to reuse some of it when
implementing our first AWS resource providers. (Although we won't be using
CloudFormation, some of the name generation code might be useful.) So, the
ships aren't completely burned to the ground, but they are certainly on 🔥.
This change encapsulates what's required for an AWS cluster in new service,
mu/clouds/aws/Cluster, so that mu/Cluster can remain fairly simplistic (it
just switches on the names and dispatches to the appropriate sub-modules).
There's no need for quotes here and having them makes it feel somehow
"dynamically typed" (I was subconsciously influenced by Go, I think).
Removing them...
This change renames a few things; more to come, but this is at least
a self-consistent checkpoint:
* Use the "new" keyword to create service objects and not "resource".
* Use the "func" keyword to indicate functions and not "macro".
* Use "bool" instead of "boolean" for boolean types (more Go-like).
First, I meant to rename "func" to "macro". This is perhaps contentious,
however my thinking was to differentiate between functions which have runtime
representations -- like lambdas, API gateway handlers, and the like -- and
macros which are purely a metadata/compile-time construct.
Second, there was a resource naming typo.
This sketches out a minimal configuration language, inspired by a combination
of the Mull document, Hashicorp's various language efforts, Protobufs, and a
mixture of TypeScript. I'm attempting to whittle down the concepts to the bare
minimum necessary for a universal "intermediate language" for our runtime that
is (a) complete enough to serve our needs, (b) advanced enough to deliver some
of the improvements in componentization and reuse that we desire, (c) appealing
enough that humans are able to write code in the language while possibly even
enjoying it, and, yet, (d) sufficient for machine interoperability needs.
Of course, I will capture all of this in a proper specification (overwriting
the existing Mull one), however I wanted to land these as a proof of concept and
for feedback purposes. Obviously, none of this code actually compiles or works!
This is a work-in-progress. In fact, it's going to radically change
given the new approach to representing resource construction, however
I wanted the snapshot in source control as we evolve things.
This demonstrates what infra-as-code might look like. Given the difficulties
in expressing everything purely as metadata, I've decided to embark upon a little
spike to see what this would look like. At first glance, I like it.
To see the difference, compare these to the Mu.yaml files alongside them.
This projects the basic AWS::ECS::TaskDefinition CloudFormation template
type as a stack. It also maps a bunch of schema types using fictitious
syntax, since we don't yet support this (see marapongo/mu#9). On to that next...
This change leverages intrinsics in place of the predefined types.
It remains to be seen if we can reach 100% on this, however I am hopeful.
It's also nice that the system will be built "out of itself" with this
approach; in other words, each of the types is simply a Mufile that can
use conditional targeting as appropriate for the given cloud providers.
If we find that this isn't enough, we can always bring back the concept.
The route resource is a bit funny, in that it lets you jam in either
an internet gateway ID or a VPC ID as the GatewayId property, whereas
all of the other target kinds get their own property. Our stack type
offers stronger typing than this (using service references), but we
need to map the resulting ref strings correctly.
I think things have gotten a little out of hand with the way mu/x/cf
auto-maps properties. In the beginning, it looked like everything could
be trivially auto-mapped, and I wanted to avoid the verbosity of mapping
each property by hand (since you can easily fat finger a name, mess up
capitalization, forget one, etc). But then we began mapping service
references using proper CloudFormation !Refs, which meant suppressing
some of the auto-mappings, etc., etc. This led to properties, extraProperties,
skipProperties, renamedProperties, and so on... Pretty confusing IMHO.
I just took a step back and decided to eliminate auto-mapping. Instead,
you get two options: properties just lists a set of property name mappings,
and extraProperties lets you do template magic to map thing instead if you
wish to take matters into your own hands. The result isn't too verbose
and has a lot less magic going on so it's easier to understand.
This change eliminates the special type mu/extension in favor of extensible
intrinsic types. This subsumes the previous functionality while also fixing
a number of warts with the old model.
In particular, the old mu/extension approach deferred property binding until
very late in the compiler. In fact, too late. The backend provider for an
extension simply received an untyped bag of stuff, which it then had to
deal with. Unfortunately, some operations in the binder are inaccessible
at this point because doing so would cause a cycle. Furthermore, some
pertinent information is gone at this point, like the scopes and symtables.
The canonical example where we need this is binding services names to the
services themselves; e.g., the AWS CloudFormation "DependsOn" property should
resolve to the actual service names, not the string values. In the limit,
this requires full binding information.
There were a few solutions I considered, including ones that've required
less code motion, however this one feels the most elegant.
Now we permit types to be marked as "intrinsic." Binding to these names
is done exactly as ordinary name binding, unlike the special mu/extension
provider name. In fact, just about everything except code-generation for
these types is the same as ordinary types. This is perfect for the use case
at hand, which is binding properties.
After this change, for example, "DependsOn" is expanded to real service
names precisely as we need.
As part of this change, I added support for three new basic schema types:
* ast.StringList ("string[]"): a list of strings.
* ast.StringMap ("map[string]any"): a map of strings to anys.
* ast.ServiceList ("service[]"): a list of service references.
Obviously we need to revisit this and add a more complete set. This work
is already tracked by marapongo/mu#9.
At the end of the day, it's likely I will replace all hard-coded predefined
types with intrinsic types, for similar reasons to the above.
Now that we're actually type-checking property types, a number of the
AWS stacks began failing, because we haven't yet mapped the full set of
resource types. I began doing that for the missing ones, but pulling on
that thread just leads to an even larger set ... (possibly all of them!)
due to extra dependencies. For now, since they aren't required for the
basic scenario, I'll just comment these out; I've logged marapongo/mu#27
to track mapping the full set of resource types.
I wasn't sure at first how we'd distinguish between strings and cap names.
At first, I thought we'd need special syntax, e.g. `<vpn>`; however, now I
am leaning towards a "type inference" approach, where we will interpret the
string as a cap name rather than string if that's what the target property
expects. Although this isn't quite as explicitly typed, that's probably a
good thing in this case, as it eliminates verbosity and weird characters.
To avoid injecting needless whitespace -- which is unfortunately meaningful
in YAML -- we need to use the new "-" trimming operators, available in Go 1.6.
This change projects several EC2 Mu stacks that are required for Mu cluster
bootstrapping. This includes:
- aws/ec2/internetGateway
- aws/ec2/route
- aws/ec2/routeTable
- aws/ec2/securityGroup
- aws/ec2/subnet
- aws/ec2/vpc
- aws/ec2/vpcGatewayAttachment
This is still not complete, and in fact some of these reference other EC2
Stacks that do not yet exist. But we're getting a bit closer...
This change adds a super simple initial whack at a basic cluster topology
comprised of VPC, subnet, internet gateway, attachments, and route tables.
This is actually written in Mu itself, and I am committing this early, since
there are quite a few features required before we can actually make progress
getting this up and running.
For now, we can simply auto-map the Mu properties to CF properties,
eliminating the need to manually map them in the templates. Eventually
we'll want more sophistication here to control various aspects of the CF
templates, but this eliminates a lot of tedious manual work in the meantime.