diff --git a/docs/chart_template_guide/accessing_files.md b/docs/chart_template_guide/accessing_files.md
index e14417fde92a36e550ee5f398c93b8bbc6a995f9..ca87469f379d1aaea6e3c48087085a7526eed016 100644
--- a/docs/chart_template_guide/accessing_files.md
+++ b/docs/chart_template_guide/accessing_files.md
@@ -9,6 +9,17 @@ Helm provides access to files through the `.Files` object. Before we get going w
 	- Files in `templates/` cannot be accessed.
 - Charts to not preserve UNIX mode information, so file-level permissions will have no impact on the availability of a file when it comes to the `.Files` object.
 
+<!-- (see https://github.com/jonschlinkert/markdown-toc) -->
+
+<!-- toc -->
+
+- [Basic example](#basic-example)
+- [Glob patterns](#glob-patterns)
+- [ConfigMap and Secrets utility functions](#configmap-and-secrets-utility-functions)
+- [Secrets](#secrets)
+
+<!-- tocstop -->
+
 ## Basic example
 
 With those caveats behind, let's write a template that reads three files into our ConfigMap. To get started, we will add three files to the chart, putting all three directly inside of the `mychart/` directory.
@@ -73,6 +84,9 @@ As your chart grows, you may find you have a greater need to organize your
 files more, and so we provide a `Files.Glob(pattern string)` method to assist
 in extracting certain files with all the flexibility of [glob patterns](//godoc.org/github.com/gobwas/glob).
 
+`.Glob` returns a `Files` type, so you may call any of the `Files` methods on
+the returned object.
+
 For example, imagine the directory structure:
 
 ```
@@ -101,6 +115,36 @@ Or
 {{ end }}
 ```
 
+## ConfigMap and Secrets utility functions
+
+(Not present in version 2.0.2 or prior)
+
+It is very common to want to place file content into both configmaps and
+secrets, for mounting into your pods at run time. To help with this, we provide a
+couple utility methods on the `Files` type.
+
+For further organization, it is especially useful to use these methods in
+conjunction with the `Glob` method.
+
+Given the directory structure from the [Glob][Glob patterns] example above:
+
+```yaml
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: conf
+data:
+{{ (.Files.Glob "foo/*").AsConfig | indent 2 }}
+---
+apiVersion: v1
+kind: Secret
+metadata:
+  name: very-secret
+type: Opaque
+data:
+{{ (.Files.Glob "bar/*").AsSecrets | indent 2 }}
+```
+
 ## Secrets
 
 When working with a Secret resource, you can import a file and have the template base-64 encode it for you:
diff --git a/pkg/chartutil/files.go b/pkg/chartutil/files.go
index ba07e5ebb909b59e7cf246905db24b43482867e0..5aa3ee3026c4ff86706110d25e92f0b84a521ec3 100644
--- a/pkg/chartutil/files.go
+++ b/pkg/chartutil/files.go
@@ -16,6 +16,11 @@ limitations under the License.
 package chartutil
 
 import (
+	"encoding/base64"
+	"path"
+
+	yaml "gopkg.in/yaml.v2"
+
 	"github.com/gobwas/glob"
 	"github.com/golang/protobuf/ptypes/any"
 )
@@ -83,3 +88,69 @@ func (f Files) Glob(pattern string) Files {
 
 	return nf
 }
+
+// AsConfig turns a Files group and flattens it to a YAML map suitable for
+// including in the `data` section of a kubernetes ConfigMap definition.
+// Duplicate keys will be overwritten, so be aware that your filenames
+// (regardless of path) should be unique.
+//
+// This is designed to be called from a template, and will return empty string
+// (via ToYaml function) if it cannot be serialized to YAML, or if the Files
+// object is nil.
+//
+// The output will not be indented, so you will want to pipe this to the
+// `indent` template function.
+//
+//   data:
+// {{ .Files.Glob("config/**").AsConfig() | indent 4 }}
+func (f Files) AsConfig() string {
+	if f == nil {
+		return ""
+	}
+
+	m := map[string]string{}
+
+	// Explicitly convert to strings, and file names
+	for k, v := range f {
+		m[path.Base(k)] = string(v)
+	}
+
+	return ToYaml(m)
+}
+
+// AsSecrets returns the value of a Files object as base64 suitable for
+// including in the `data` section of a kubernetes Secret definition.
+// Duplicate keys will be overwritten, so be aware that your filenames
+// (regardless of path) should be unique.
+//
+// This is designed to be called from a template, and will return empty string
+// (via ToYaml function) if it cannot be serialized to YAML, or if the Files
+// object is nil.
+//
+// The output will not be indented, so you will want to pipe this to the
+// `indent` template function.
+//
+//   data:
+// {{ .Files.Glob("secrets/*").AsSecrets() }}
+func (f Files) AsSecrets() string {
+	if f == nil {
+		return ""
+	}
+
+	m := map[string]string{}
+
+	for k, v := range f {
+		m[path.Base(k)] = base64.StdEncoding.EncodeToString(v)
+	}
+
+	return ToYaml(m)
+}
+
+func ToYaml(v interface{}) string {
+	data, err := yaml.Marshal(v)
+	if err != nil {
+		// Swallow errors inside of a template.
+		return ""
+	}
+	return string(data)
+}
diff --git a/pkg/chartutil/files_test.go b/pkg/chartutil/files_test.go
index 268ac1abd84a8c6ff2be4ccc178529032acf2261..afc8214b2d17550c7e4918305387fb70f0ff2a2b 100644
--- a/pkg/chartutil/files_test.go
+++ b/pkg/chartutil/files_test.go
@@ -19,6 +19,7 @@ import (
 	"testing"
 
 	"github.com/golang/protobuf/ptypes/any"
+	"github.com/stretchr/testify/assert"
 )
 
 var cases = []struct {
@@ -55,16 +56,45 @@ func TestNewFiles(t *testing.T) {
 }
 
 func TestFileGlob(t *testing.T) {
+	as := assert.New(t)
+
 	f := NewFiles(getTestFiles())
 
 	matched := f.Glob("story/**")
 
-	if len(matched) != 2 {
-		t.Errorf("Expected two files in glob story/**, got %d", len(matched))
+	as.Len(matched, 2, "Should be two files in glob story/**")
+	as.Equal("Joseph Conrad", matched.Get("story/author.txt"))
+}
+
+func TestToConfig(t *testing.T) {
+	as := assert.New(t)
+
+	f := NewFiles(getTestFiles())
+	out := f.Glob("**/captain.txt").AsConfig()
+	as.Equal("captain.txt: The Captain\n", out)
+
+	out = f.Glob("ship/**").AsConfig()
+	as.Equal("captain.txt: The Captain\nstowaway.txt: Legatt\n", out)
+}
+
+func TestToSecret(t *testing.T) {
+	as := assert.New(t)
+
+	f := NewFiles(getTestFiles())
+
+	out := f.Glob("ship/**").AsSecrets()
+	as.Equal("captain.txt: VGhlIENhcHRhaW4=\nstowaway.txt: TGVnYXR0\n", out)
+}
+
+func TestToYaml(t *testing.T) {
+	expect := "foo: bar\n"
+	v := struct {
+		Foo string `json:"foo"`
+	}{
+		Foo: "bar",
 	}
 
-	m, expect := matched.Get("story/author.txt"), "Joseph Conrad"
-	if m != expect {
-		t.Errorf("Wrong globbed file content. Expected %s, got %s", expect, m)
+	if got := ToYaml(v); got != expect {
+		t.Errorf("Expected %q, got %q", expect, got)
 	}
 }
diff --git a/pkg/engine/engine.go b/pkg/engine/engine.go
index bdc4011d7bbb95e7a2c9f60e5b6dca079e7c8a67..c7998b78d677eeb1917e292ebf0f65ef9bc43653 100644
--- a/pkg/engine/engine.go
+++ b/pkg/engine/engine.go
@@ -24,7 +24,6 @@ import (
 	"text/template"
 
 	"github.com/Masterminds/sprig"
-	"github.com/ghodss/yaml"
 
 	"k8s.io/helm/pkg/chartutil"
 	"k8s.io/helm/pkg/proto/hapi/chart"
@@ -69,26 +68,28 @@ func FuncMap() template.FuncMap {
 	delete(f, "env")
 	delete(f, "expandenv")
 
-	// Add a function to convert to YAML:
-	f["toYaml"] = toYaml
+	// Add some extra functionality
+	extra := template.FuncMap{
+		"toYaml": files.ToYaml,
+		"base":   path.Base,
+		"dir":    path.Dir,
+		"ext":    path.Ext,
+		"isAbs":  path.IsAbs,
+		"clean":  path.Clean,
+
+		// This is a placeholder for the "include" function, which is
+		// late-bound to a template. By declaring it here, we preserve the
+		// integrity of the linter.
+		"include": func(string, interface{}) string { return "not implemented" },
+	}
 
-	// This is a placeholder for the "include" function, which is
-	// late-bound to a template. By declaring it here, we preserve the
-	// integrity of the linter.
-	f["include"] = func(string, interface{}) string { return "not implemented" }
+	for k, v := range extra {
+		f[k] = v
+	}
 
 	return f
 }
 
-func toYaml(v interface{}) string {
-	data, err := yaml.Marshal(v)
-	if err != nil {
-		// Swallow errors inside of a template.
-		return ""
-	}
-	return string(data)
-}
-
 // Render takes a chart, optional values, and value overrides, and attempts to render the Go templates.
 //
 // Render can be called repeatedly on the same engine.
diff --git a/pkg/engine/engine_test.go b/pkg/engine/engine_test.go
index 2804dfbab756b6323bc33ec38d402157a73c57ef..3ee94cac19f7745a6327fece5bc068399e4983bb 100644
--- a/pkg/engine/engine_test.go
+++ b/pkg/engine/engine_test.go
@@ -27,19 +27,6 @@ import (
 	"github.com/golang/protobuf/ptypes/any"
 )
 
-func TestToYaml(t *testing.T) {
-	expect := "foo: bar\n"
-	v := struct {
-		Foo string `json:"foo"`
-	}{
-		Foo: "bar",
-	}
-
-	if got := toYaml(v); got != expect {
-		t.Errorf("Expected %q, got %q", expect, got)
-	}
-}
-
 func TestEngine(t *testing.T) {
 	e := New()