[openstack-dev] [Heat] A concrete proposal for Heat Providers
Angus Salkeld
asalkeld at redhat.com
Fri Apr 26 01:35:36 UTC 2013
On 25/04/13 21:35 +0200, Zane Bitter wrote:
>Greetings Heaters,
>I'm hearing a lot about (and struggling to keep track of) multiple
>people working on competing proposals for how a Heat template
>language should look if we designed it from scratch and, while that's
>valuable in helping to figure out the primitives we need, I'd also
>like to approach it from the other direction and start figuring out
>what path we need to get on to bring the new feature direction that
>our users want to fruition. We all agreed at the Summit that we need
>to pursue these new features in an incremental manner, and we should
>not forget *why*:
>
> A complex system that works is invariably found to have evolved
> from a simple system that worked.
> -- http://en.wikipedia.org/wiki/Gall's_law
>
>What follows is a concrete proposal for how we could implement one of
>the requested features, starting from use cases, through the
>predicted code changes required and looping back around to user
>benefits. It certainly does not purport to implement every feature
>requested by users. It is likely wrong in the particulars, certainly
>in ways that will not be discovered at least until we have
>implemented it. But it is a concrete proposal. It begins with an
>excellent summary of the use case from Adrian...
>
>
>On 13/04/13 00:36, Adrian Otto wrote:
>> Goal: Deploy my app on my chosen OpenStack based public cloud,
>using Heat for Dev/Test. For Production, deploy to my private
>OpenStack cloud.
>>
>> Scenario: My app depends on a MySQL database. My public cloud
>provider has a hosted "mysql" service that is offered through a
>Provider plug-in. It's there automatically because my cloud hosting
>company put it there. I deploy, and finish my testing on the public
>cloud. I want to go to production now.
>>
>> Solution: The Provider gives you a way to abstract the different
>cloud implementations. I establish an equivalent Provider on my
>private OpenStack cloud using RedDwarf. I set up a Provider that
>offers "mysql" in my private cloud. Now the same setup works on both
>clouds, even though the API for my local "mysql" service may actually
>differ from the database provisioning API in the public cloud. Now I
>deploy on my "production" Environment in my private cloud, and it
>works!
>
>So, the first and most important thing to note is that this is
>exactly how Heat works _now_.
>
>There is a resource type called AWS::RDS::DBInstance and the operator
>of your cloud can choose a plugin to implement that interface. The
>plugin shipping with Heat actually just spins up a somewhat hacky
>Heat stack running MySQL... in future we hope to ship a RedDwarf Lite
>plugin, and of course any cloud provider with their own DBaaS could
>easily write a plugin to interface with that. (Note that when we do
>see a RedDwarf Lite plugin we'll probably also see a variant called
>something like OS::RedDwarf::DBInstance with more OpenStack-specific
>properties &c.)
>
>So that's how Heat works today. How can we make this better? Well,
>one thing obviously sucks: your cloud operator, and not you, gets to
>decide which plugin is used. That sorta makes sense when it's an
>interface to an XaaS thing in their cloud, but if it's just a Nova
>instance running MySQL and you don't like the version your operator
>has gone with, you are SOL. You can try running your own Heat engine,
>but you're probably going to have to really hack at it first because
>whenever anything in-guest has to talk back to you, the endpoint is
>obtained from the same Keystone catalog that you're using to talk to
>the other services. And no cloud operator in the world - not even
>your friendly local IT department - is going to let users upload
>Python code to run in-memory in their orchestration engine along with
>all of the other users' code.
>
>If only there were some sort of language for defining OpenStack
>services that could be safely executed by users...
>
>Of course that's exactly what we're all about on this project :). So
>my proposal is to allow users to define their own resource types
>using a Heat template. Heat would know to use this template instead
>of a built-in type from a "Provider" member in the Resource
>definition that contains a URL to the template. (I'm appropriating
>the name "Provider" from Rackspace's DSL proposal for now because
>inventing new names for things that already exist is a sucker's
>game.)
>
>These are the tasks that come to mind that would be required to
>implement this (each of these bullet points could become a
>blueprint):
>
>* Create a Custom resource type that is based on a nested stack but,
>unlike the AWS::CloudFormation::Stack type, has properties and
>attributes inferred from the parameters and outputs (respectively) of
>the template provided.
So this is to convert from resource properties defined in the
DBInstance to the nested stack parameters (and to make sure they
match up).
>* Allow JSON values for parameters.
>* Introduce the concept of _stack_ Metadata, and provide a way to
>access it in a template (pseudo-parameter?).
>* Modify resource instantiation to create a Custom resource whenever
>a resource has a non-empty "Provider" attribute.
>* Introduce a schema for attributes (i.e. allowed arguments to
>Fn::GetAttr) [desirable anyway for autogenerating documentation]
>* Add an API to get a generic template version of any built-in
>resource (with all properties/outputs defined) that can be easily
>customised to make a new provider template.
>
>A possible avenue for increasing flexibility:
>* Add support for more template functions that manipulate the
>template directly:
> - Array/dictionary (uh, object) lookup
> - more string functions?
> - maybe conditionals?
> - definitely NOT loops/map.
>
>What might all of this give us?
> + Users are no longer dependent on the operator to provide the
>resource type they need (perhaps for cross-cloud compatibility), but
>can supply their own.
> + Users can effectively subclass built-in types. For example, you
>could create a Puppet Instance template that configures an instance
>as a Puppet slave, then selectively use that in place of a regular
>instance and just pass the metadata to specialise it.
> + Users can share their provider templates: as soon as a second
>person is trying to configure a puppet slave in a template we're
>wasting an opportunity - this will enable work like that to be
>shared.
> + This is infinitely flexible at the platform layer - anybody
>(Puppet, Chef, OpenShift, &c.) can publish an Instance provider
>template
>
>How else might we improve this? Well, having to load a template from
>a URL is definitely a limitation - albeit not a new one (the
>AWS::CloudFormation::Stack resource type already has this
>limitation). Perhaps we should let the user post multiple, named,
>implementations of a resource type and reference them by name
>(instead of URL) in the "Provider" field.
>
>* Modify the resource instantiation to search among multiple named
>definitions (either Custom or Plugin) for a resource type, according
>to the "Provider" name.
>* Add an API for posting multiple named implementations of a resource type.
>
> + The user can modify the default Provider for a resource if they so
>desire (but this is tenant-wide... or perhaps that's where
>Environments come in).
> + Provider templates can be uploaded directly to Heat instead of
>e.g. to Swift.
> + Operators can reuse the mechanism to provide versioned Plugins
>and/or multiple implementations of Resource types.
>
Nice Zane,
Just to clarify what this gives the user....
vim ~/my_hot_nested_stacks/foo.template
heat publish-template --private ~/my_hot_nested_stacks/foo.template --type "AWS::RDS::DBInstance"
(returns the url to the template)
http://..../foo.template
So now we have a user generated nested stack that can replace the
builtin one (and the mechanism to do the mapping).
now I just use any template that uses a "AWS::RDS::DBInstance"
resource and my nested stack is used.
So this does not need the provider except when you what if you want to control
the implementation:
heat publish-template --private \
https://github.com/zaneb/hot-templates/raw/master/db.templ --type "AWS::RDS::DBInstance"
heat template-list
AWS::RDS::DBInstance builtin
AWS::RDS::DBInstance http://..../foo.template
AWS::RDS::DBInstance https://github.com/zaneb/hot-templates/raw/master/db.templ
when I create a stack I do something like the following:
heat create teststack -f myapp.template -P "InstanceType=m1.large;KeyName=heat_key" --use "AWS::RDS::DBInstance=http://..../foo.template"
That looks messy so it might make sense to use the environment idea to
define the mapping of ResourceType to nested stack.
General question:
Do we want to support different providers of the same Resource type
within the same template? - I assume yes.
If I were to suggest baby steps:
1) have property valid on all resources "provider_url"
prove you can start an inbuilt resource from a
nested stack template with all the property validation goodness.
2) add "heat publish-template/list-templates/.."
3) add the environment concept to make defining the mapping more user
friendly - this would just set the "provider_url" property on the
resources so you don't have to edit templates or have super long
command lines.
More crazy ideas:
what about starting a db instance as a normal stack and then
"attaching" to it? It's just a stack after all (it's just already
running).
heat stack-create wordpress -f wp.templ -P "..." \
--use "AWS::RDS::DBInstance=stack-url"
This way you could reuse services (might need a refcount tho').
Any one see this as a good idea?
-Angus
>
>So, in summary, this plan appears to provide real, identified value
>to users; relies for the most part on existing technology in Heat
>(nested stacks are actually pretty cool, if I may say so); includes a
>series of changes required to implement the feature; has zero impact
>on existing users; does not IMO decrease maintainability of the Heat
>code base; and is entirely achievable before the Havana feature
>freeze, which is only ~4 months from now.
>
>That said, I am not wedded to any of the particular details of this
>proposal - though I do regard it as a real proposal, not just a straw
>man. If anybody has suggestions for where I've got the requirements,
>concepts or implementation ideas wrong then rip in. But I'd love to
>hear either a discussion at the level of these concrete details or a
>competing proposal at a similar level.
>
>
>For easier collation, please categorise your response as follows:
> (A) I'm appalled at the mere suggestion
> (B) This just prevents us solving the real problem (please specify)
> (C) Meh
> (D) This looks kind of interesting
> (E) OMG!! UNICORNS!!!
>
>;)
>
>cheers,
>Zane.
>
>_______________________________________________
>OpenStack-dev mailing list
>OpenStack-dev at lists.openstack.org
>http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
More information about the OpenStack-dev
mailing list