Skip to content
This repository has been archived by the owner on Dec 21, 2018. It is now read-only.

Scoped Resources A Modest Proposal

Julian C. Dunn edited this page Oct 5, 2014 · 1 revision

Scoped Resources

Friday, Leschi, 10:00am

Convener

John Keiser (@jkeiser)

Participants

@jkeiser, @coderanger, et. al.

Summary of Discussions

Hierarchical resources! Adding (meaningful) dots to a resource name allow us to declare new specialized resources that inherit from already-loaded resources. (John is very careful not to say 'subclass' as that has specific connotations with regard to the implementation of the idea which may or may not be compatible with Chef)

This should look familiar to those who are familiar with Poise (http://poise.io).

Resource Specialization

Example given (from butcher paper):

# recipe block is inferred from simply loading the recipe, so 
# that declared resources are scoped to a single recipe by default 
# in this scheme.
recipe :default do
  resource :file, file do
    attribute :mode, :default => '0755'
  end
  # this will be created with mode 0755 because of the above definition.
  file "/tmp/hello_world"
    contents "Hi"
  end
end

# if you want to override the resource for the entire cookbook 
# scope, use "cookbook" instead of "recipe" above.

The goal here is to DRY up your Chef recipes without overriding global resource defaults (which can potentially break contracts with other cookbooks).

Another example:

# cookbook my_app::aws
# attribute names are examples only.
resource :small_machine, aws.machine do
  ami "some-ami-image-name"
  instance_type "x-small"
end

#
# cookbook my_app::application
#
small_machine "web"
small_machine "db"
# etc.
# another means of invocation:
aws.machine.small_machine "cache"

One problem raised: What happens if you override all the defaults for a cookbook-scoped resource in one recipe in the cookbook? What happens to the other resources declared earlier in scope? (Answer: This is evaluated at compile-time, so whatever happens first in compile order goes.)

Another: What about LWRPs? (Answer: They run in a different context and therefore won't be overridden.)

Q: Would there be cases where you'd then build resources that are intentionally "fuzzy" and not intended to be used directly without being scoped?

A: Hadn't thought of that, but possibly.

Q: How would you implement a library cookbook?

A: (Not answered in detail.)

Q: Is this putting a greater cognitive load on newcomers by having "library recipes?"

A: (Under debate. The bigger load may actually be on existing Chef users...)

Containment

Example goal: I want to write a cookbook for working with GitHub.

#github cookbook:

resource :github
  attribute :api_token # ...
  attribute :web_url # ...
  resource :organization
    # inherits github endpoint attributes from parent
    resource :repository
      # inherits organization name and other attributes
      attribute :name
      attribute :description
      resource :issue
        attribute :id
        attribute :long_desc
      end
    end
  end
end

opscode = github.organization("opscode")
opscode do
  repository("chef") do
    issue 1, :long_desc => "blah"
    issue 2, :long_desc => "foo"
  end
end

What will we do now? What needs to happen next?

Next steps are basically for more people to take a look at this and shoot holes in the idea. It's likely that my notes aren't capturing the idea and conversation precisely.

Clone this wiki locally