diff --git a/builtin/providers/docker/resource_docker_container.go b/builtin/providers/docker/resource_docker_container.go
index 2fb4efc29..6bc03de3e 100644
--- a/builtin/providers/docker/resource_docker_container.go
+++ b/builtin/providers/docker/resource_docker_container.go
@@ -138,6 +138,33 @@ func resourceDockerContainer() *schema.Resource {
ForceNew: true,
},
+ "capabilities": &schema.Schema{
+ Type: schema.TypeSet,
+ Optional: true,
+ ForceNew: true,
+ MaxItems: 1,
+ Elem: &schema.Resource{
+ Schema: map[string]*schema.Schema{
+ "add": &schema.Schema{
+ Type: schema.TypeSet,
+ Optional: true,
+ ForceNew: true,
+ Elem: &schema.Schema{Type: schema.TypeString},
+ Set: schema.HashString,
+ },
+
+ "drop": &schema.Schema{
+ Type: schema.TypeSet,
+ Optional: true,
+ ForceNew: true,
+ Elem: &schema.Schema{Type: schema.TypeString},
+ Set: schema.HashString,
+ },
+ },
+ },
+ Set: resourceDockerCapabilitiesHash,
+ },
+
"volumes": &schema.Schema{
Type: schema.TypeSet,
Optional: true,
@@ -396,6 +423,21 @@ func resourceDockerContainer() *schema.Resource {
}
}
+func resourceDockerCapabilitiesHash(v interface{}) int {
+ var buf bytes.Buffer
+ m := v.(map[string]interface{})
+
+ if v, ok := m["add"]; ok {
+ buf.WriteString(fmt.Sprintf("%v-", v))
+ }
+
+ if v, ok := m["remove"]; ok {
+ buf.WriteString(fmt.Sprintf("%v-", v))
+ }
+
+ return hashcode.String(buf.String())
+}
+
func resourceDockerPortsHash(v interface{}) int {
var buf bytes.Buffer
m := v.(map[string]interface{})
diff --git a/builtin/providers/docker/resource_docker_container_funcs.go b/builtin/providers/docker/resource_docker_container_funcs.go
index f74264a77..ba7d54aa2 100644
--- a/builtin/providers/docker/resource_docker_container_funcs.go
+++ b/builtin/providers/docker/resource_docker_container_funcs.go
@@ -126,6 +126,15 @@ func resourceDockerContainerCreate(d *schema.ResourceData, meta interface{}) err
hostConfig.VolumesFrom = volumesFrom
}
+ if v, ok := d.GetOk("capabilities"); ok {
+ for _, capInt := range v.(*schema.Set).List() {
+ capa := capInt.(map[string]interface{})
+ hostConfig.CapAdd = stringSetToStringSlice(capa["add"].(*schema.Set))
+ hostConfig.CapDrop = stringSetToStringSlice(capa["drop"].(*schema.Set))
+ break
+ }
+ }
+
if v, ok := d.GetOk("dns"); ok {
hostConfig.DNS = stringSetToStringSlice(v.(*schema.Set))
}
diff --git a/builtin/providers/docker/resource_docker_container_test.go b/builtin/providers/docker/resource_docker_container_test.go
index 99f0ab3e9..1da7e87e6 100644
--- a/builtin/providers/docker/resource_docker_container_test.go
+++ b/builtin/providers/docker/resource_docker_container_test.go
@@ -128,6 +128,22 @@ func TestAccDockerContainer_customized(t *testing.T) {
return fmt.Errorf("Container has wrong dns search setting: %v", c.HostConfig.DNS[0])
}
+ if len(c.HostConfig.CapAdd) != 1 {
+ return fmt.Errorf("Container does not have the correct number of Capabilities in ADD: %d", len(c.HostConfig.CapAdd))
+ }
+
+ if c.HostConfig.CapAdd[0] != "ALL" {
+ return fmt.Errorf("Container has wrong CapAdd setting: %v", c.HostConfig.CapAdd[0])
+ }
+
+ if len(c.HostConfig.CapDrop) != 1 {
+ return fmt.Errorf("Container does not have the correct number of Capabilities in Drop: %d", len(c.HostConfig.CapDrop))
+ }
+
+ if c.HostConfig.CapDrop[0] != "SYS_ADMIN" {
+ return fmt.Errorf("Container has wrong CapDrop setting: %v", c.HostConfig.CapDrop[0])
+ }
+
if c.HostConfig.CPUShares != 32 {
return fmt.Errorf("Container has wrong cpu shares setting: %d", c.HostConfig.CPUShares)
}
@@ -311,6 +327,12 @@ resource "docker_container" "foo" {
memory = 512
memory_swap = 2048
cpu_shares = 32
+
+ capabilities {
+ add= ["ALL"]
+ drop = ["SYS_ADMIN"]
+ }
+
dns = ["8.8.8.8"]
dns_opts = ["rotate"]
dns_search = ["example.com"]
diff --git a/website/source/docs/providers/docker/r/container.html.markdown b/website/source/docs/providers/docker/r/container.html.markdown
index 77783a906..8a7671591 100644
--- a/website/source/docs/providers/docker/r/container.html.markdown
+++ b/website/source/docs/providers/docker/r/container.html.markdown
@@ -62,6 +62,7 @@ The following arguments are supported:
* `must_run` - (Optional, bool) If true, then the Docker container will be
kept running. If false, then as long as the container exists, Terraform
assumes it is successful.
+* `capabilities` - (Optional, block) See [Capabilities](#capabilities) below for details.
* `ports` - (Optional, block) See [Ports](#ports) below for details.
* `host` - (Optional, block) See [Extra Hosts](#extra_hosts) below for
details.
@@ -82,6 +83,27 @@ The following arguments are supported:
* `destroy_grace_seconds` - (Optional, int) If defined will attempt to stop the container before destroying. Container will be destroyed after `n` seconds or on successful stop.
* `upload` - (Optional, block) See [File Upload](#upload) below for details.
+
+### Capabilities
+
+`capabilities` is a block within the configuration that allows you to add or drop linux capabilities. For more information about what capabilities you can add and drop please visit the docker run documentation.
+
+* `add` - (Optional, set of strings) list of linux capabilities to add.
+* `drop` - (Optional, set of strings) list of linux capabilities to drop.
+
+Example:
+
+```
+resource "docker_container" "ubuntu" {
+ name = "foo"
+ image = "${docker_image.ubuntu.latest}"
+ capabilities {
+ add = ["ALL"]
+ drop = ["SYS_ADMIN"]
+ }
+}
+```
+
### Ports