Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion docs/resources/service.md
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,9 @@ Optional:

- `credential_spec` (Block List, Max: 1) CredentialSpec for managed service account (Windows only) (see [below for nested schema](#nestedblock--task_spec--container_spec--privileges--credential_spec))
- `se_linux_context` (Block List, Max: 1) SELinux labels of the container (see [below for nested schema](#nestedblock--task_spec--container_spec--privileges--se_linux_context))
- `seccomp` (Block List, Max: 1) Seccomp options for container. Modes: default, unconfined, custom. (see [below for nested schema](#nestedblock--task_spec--container_spec--privileges--seccomp))
- `apparmor` (Block List, Max: 1) AppArmor options for container. Modes: default, disabled. (see [below for nested schema](#nestedblock--task_spec--container_spec--privileges--apparmor))


<a id="nestedblock--task_spec--container_spec--privileges--credential_spec"></a>
### Nested Schema for `task_spec.container_spec.privileges.credential_spec`
Expand All @@ -528,6 +531,22 @@ Optional:
- `user` (String) SELinux user label


<a id="nestedblock--task_spec--container_spec--privileges--seccomp"></a>
### Nested Schema for `task_spec.container_spec.privileges.seccomp`

Optional:

- `mode` (String) Seccomp mode: default, unconfined or custom
- `profile` (String) Custom seccomp profile in JSON format (required if mode is 'custom')


<a id="nestedblock--task_spec--container_spec--privileges--apparmor"></a>
### Nested Schema for `task_spec.container_spec.privileges.apparmor`

Optional:

- `mode` (String) AppArmor mode: default or disabled


<a id="nestedblock--task_spec--container_spec--secrets"></a>
### Nested Schema for `task_spec.container_spec.secrets`
Expand Down Expand Up @@ -784,4 +803,4 @@ then the import command is as follows
```shell
#!/bin/bash
terraform import docker_service.foo 4pcphbxkfn2rffhbhe6czytgi
```
```
6 changes: 6 additions & 0 deletions examples/resources/docker_service/resource-advanced.tf
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ resource "docker_service" "foo" {
type = "type-label"
level = "level-label"
}
seccomp {
mode = "default"
}
apparmor {
mode = "default"
}
}

read_only = true
Expand Down
35 changes: 35 additions & 0 deletions internal/provider/resource_docker_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,41 @@ func resourceDockerService() *schema.Resource {
},
},
},
"seccomp": {
Type: schema.TypeList,
MaxItems: 1,
Optional: true,
Description: "Seccomp options for container. Modes: default, unconfined, custom.",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"mode": {
Type: schema.TypeString,
Description: "Seccomp mode: default, unconfined or custom",
Optional: true,
},
"profile": {
Type: schema.TypeString,
Description: "Custom seccomp profile in JSON format (required if mode is 'custom')",
Optional: true,
},
},
},
},
"apparmor": {
Type: schema.TypeList,
MaxItems: 1,
Optional: true,
Description: "AppArmor options for container security profile. Modes: default, disabled.",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"mode": {
Type: schema.TypeString,
Description: "AppArmor mode: default or disabled",
Optional: true,
},
},
},
},
},
},
},
Expand Down
60 changes: 60 additions & 0 deletions internal/provider/resource_docker_service_migrators.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,36 @@ func resourceDockerServiceV1() *schema.Resource {
},
},
},
"seccomp": {
Type: schema.TypeList,
MaxItems: 1,
Optional: true,
Description: "Seccomp options for container. Modes: default, unconfined.",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"mode": {
Type: schema.TypeString,
Description: "Seccomp mode: default or unconfined",
Optional: true,
},
},
},
},
"apparmor": {
Type: schema.TypeList,
MaxItems: 1,
Optional: true,
Description: "AppArmor options for container. Modes: default, disabled.",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"mode": {
Type: schema.TypeString,
Description: "AppArmor mode: default or disabled",
Optional: true,
},
},
},
},
},
},
},
Expand Down Expand Up @@ -1131,6 +1161,36 @@ func resourceDockerServiceV0() *schema.Resource {
},
},
},
"seccomp": {
Type: schema.TypeList,
MaxItems: 1,
Optional: true,
Description: "Seccomp options for container. Modes: default, unconfined.",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"mode": {
Type: schema.TypeString,
Description: "Seccomp mode: default or unconfined",
Optional: true,
},
},
},
},
"apparmor": {
Type: schema.TypeList,
MaxItems: 1,
Optional: true,
Description: "AppArmor options for container. Modes: default, disabled.",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"mode": {
Type: schema.TypeString,
Description: "AppArmor mode: default or disabled",
Optional: true,
},
},
},
},
},
},
},
Expand Down
45 changes: 45 additions & 0 deletions internal/provider/resource_docker_service_structures.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,26 @@ func flattenPrivileges(in *swarm.Privileges) []interface{} {
seLinuxContext[0] = internal
m["se_linux_context"] = seLinuxContext
}

if in.Seccomp != nil {
seccomp := make([]interface{}, 1)
internal := make(map[string]interface{})
internal["mode"] = string(in.Seccomp.Mode)
if in.Seccomp.Mode == swarm.SeccompModeCustom && len(in.Seccomp.Profile) > 0 {
internal["profile"] = string(in.Seccomp.Profile)
}
seccomp[0] = internal
m["seccomp"] = seccomp
}

if in.AppArmor != nil {
apparmor := make([]interface{}, 1)
internal := make(map[string]interface{})
internal["mode"] = string(in.AppArmor.Mode)
apparmor[0] = internal
m["apparmor"] = apparmor
}

out[0] = m
return out
}
Expand Down Expand Up @@ -769,6 +789,31 @@ func createContainerSpec(v interface{}) (*swarm.ContainerSpec, error) {
}
}
}
if value, ok := rawPrivilegesSpec["seccomp"]; ok {
if len(value.([]interface{})) > 0 {
containerSpec.Privileges.Seccomp = &swarm.SeccompOpts{}
for _, rawSeccomp := range value.([]interface{}) {
rawSeccomp := rawSeccomp.(map[string]interface{})
if v, ok := rawSeccomp["mode"]; ok {
containerSpec.Privileges.Seccomp.Mode = swarm.SeccompMode(v.(string))
}
if v, ok := rawSeccomp["profile"]; ok {
containerSpec.Privileges.Seccomp.Profile = []byte(v.(string))
}
}
}
}
if value, ok := rawPrivilegesSpec["apparmor"]; ok {
if len(value.([]interface{})) > 0 {
containerSpec.Privileges.AppArmor = &swarm.AppArmorOpts{}
for _, rawAppArmor := range value.([]interface{}) {
rawAppArmor := rawAppArmor.(map[string]interface{})
if v, ok := rawAppArmor["mode"]; ok {
containerSpec.Privileges.AppArmor.Mode = swarm.AppArmorMode(v.(string))
}
}
}
}
}
}
}
Expand Down
12 changes: 12 additions & 0 deletions internal/provider/resource_docker_service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,16 @@ func TestAccDockerService_fullSpec(t *testing.T) {
return fmt.Errorf("Service Spec.TaskTemplate.ContainerSpec.Privileges.SELinuxContext is wrong: %v", s.Spec.TaskTemplate.ContainerSpec.Privileges.SELinuxContext)
}

if s.Spec.TaskTemplate.ContainerSpec.Privileges.Seccomp == nil ||
s.Spec.TaskTemplate.ContainerSpec.Privileges.Seccomp.Mode != swarm.SeccompModeDefault {
return fmt.Errorf("Service Spec.TaskTemplate.ContainerSpec.Privileges.Seccomp is wrong: %v", s.Spec.TaskTemplate.ContainerSpec.Privileges.Seccomp)
}

if s.Spec.TaskTemplate.ContainerSpec.Privileges.AppArmor == nil ||
s.Spec.TaskTemplate.ContainerSpec.Privileges.AppArmor.Mode != swarm.AppArmorModeDefault {
return fmt.Errorf("Service Spec.TaskTemplate.ContainerSpec.Privileges.AppArmor is wrong: %v", s.Spec.TaskTemplate.ContainerSpec.Privileges.AppArmor)
}

if s.Spec.TaskTemplate.ContainerSpec.StopSignal == "" ||
s.Spec.TaskTemplate.ContainerSpec.StopSignal != "SIGTERM" {
return fmt.Errorf("Service Spec.TaskTemplate.ContainerSpec.StopSignal is wrong: %s", s.Spec.TaskTemplate.ContainerSpec.StopSignal)
Expand Down Expand Up @@ -600,6 +610,8 @@ func TestAccDockerService_fullSpec(t *testing.T) {
resource.TestCheckResourceAttr("docker_service.foo", "task_spec.0.container_spec.0.privileges.0.se_linux_context.0.role", "role-label"),
resource.TestCheckResourceAttr("docker_service.foo", "task_spec.0.container_spec.0.privileges.0.se_linux_context.0.type", "type-label"),
resource.TestCheckResourceAttr("docker_service.foo", "task_spec.0.container_spec.0.privileges.0.se_linux_context.0.level", "level-label"),
resource.TestCheckResourceAttr("docker_service.foo", "task_spec.0.container_spec.0.privileges.0.seccomp.0.mode", "default"),
resource.TestCheckResourceAttr("docker_service.foo", "task_spec.0.container_spec.0.privileges.0.apparmor.0.mode", "default"),
resource.TestCheckResourceAttr("docker_service.foo", "task_spec.0.container_spec.0.read_only", "true"),
resource.TestCheckResourceAttr("docker_service.foo", "task_spec.0.container_spec.0.mounts.0.target", "/mount/test2"),
resource.TestCheckResourceAttr("docker_service.foo", "task_spec.0.container_spec.0.mounts.0.source", "tftest-volume-2"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,12 @@ resource "docker_service" "foo" {
type = "type-label"
level = "level-label"
}
seccomp {
mode = "default"
}
apparmor {
mode = "default"
}
}

read_only = true
Expand Down Expand Up @@ -175,7 +181,7 @@ resource "docker_service" "foo" {

force_update = 0
runtime = "container"

networks_advanced {
name = docker_network.test_network.id
aliases = ["tftest-foobar"]
Expand Down