diff --git a/.changelog/1892.txt b/.changelog/1892.txt new file mode 100644 index 0000000000..ea3086af67 --- /dev/null +++ b/.changelog/1892.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +Add fs_group_change_policy to security_context +``` diff --git a/kubernetes/resource_kubernetes_pod_test.go b/kubernetes/resource_kubernetes_pod_test.go index f0dcc50c50..fde79853f4 100644 --- a/kubernetes/resource_kubernetes_pod_test.go +++ b/kubernetes/resource_kubernetes_pod_test.go @@ -296,6 +296,64 @@ func TestAccKubernetesPod_with_pod_security_context(t *testing.T) { }) } +func TestAccKubernetesPod_with_pod_security_context_fs_group_change_policy(t *testing.T) { + var conf api.Pod + + podName := acctest.RandomWithPrefix("tf-acc-test") + imageName := nginxImageVersion + resourceName := "kubernetes_pod.test" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t); skipIfUnsupportedSecurityContextRunAsGroup(t) }, + ProviderFactories: testAccProviderFactories, + CheckDestroy: testAccCheckKubernetesPodDestroy, + Steps: []resource.TestStep{ + { + Config: testAccKubernetesPodConfigWithSecurityContextFSChangePolicy(podName, imageName), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckKubernetesPodExists(resourceName, &conf), + resource.TestCheckResourceAttr(resourceName, "spec.0.security_context.0.fs_group", "100"), + resource.TestCheckResourceAttr(resourceName, "spec.0.security_context.0.run_as_group", "100"), + resource.TestCheckResourceAttr(resourceName, "spec.0.security_context.0.run_as_non_root", "true"), + resource.TestCheckResourceAttr(resourceName, "spec.0.security_context.0.run_as_user", "101"), + resource.TestCheckResourceAttr(resourceName, "spec.0.security_context.0.fs_group_change_policy", "OnRootMismatch"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"metadata.0.resource_version"}, + }, + }, + }) +} + +func testAccKubernetesPodConfigWithSecurityContextFSChangePolicy(podName, imageName string) string { + return fmt.Sprintf(`resource "kubernetes_pod" "test" { + metadata { + labels = { + app = "pod_label" + } + name = "%s" + } + spec { + security_context { + fs_group = 100 + run_as_group = 100 + run_as_non_root = true + run_as_user = 101 + fs_group_change_policy = "OnRootMismatch" + } + container { + image = "%s" + name = "containername" + } + } +} +`, podName, imageName) +} + func TestAccKubernetesPod_with_pod_security_context_run_as_group(t *testing.T) { var conf api.Pod diff --git a/kubernetes/schema_pod_spec.go b/kubernetes/schema_pod_spec.go index bacbd29288..288363612c 100644 --- a/kubernetes/schema_pod_spec.go +++ b/kubernetes/schema_pod_spec.go @@ -301,6 +301,16 @@ func podSpecFields(isUpdatable, isComputed bool) map[string]*schema.Schema { Schema: seLinuxOptionsField(isUpdatable), }, }, + "fs_group_change_policy": { + Type: schema.TypeString, + Description: "fsGroupChangePolicy defines behavior of changing ownership and permission of the volume before being exposed inside Pod. This field will only apply to volume types which support fsGroup based ownership(and permissions). It will have no effect on ephemeral volume types such as: secret, configmaps and emptydir.", + Optional: true, + ValidateFunc: validation.StringInSlice([]string{ + string(api.FSGroupChangeAlways), + string(api.FSGroupChangeOnRootMismatch), + }, false), + ForceNew: !isUpdatable, + }, "supplemental_groups": { Type: schema.TypeSet, Description: "A list of groups applied to the first process run in each container, in addition to the container's primary GID. If unspecified, no groups will be added to any container.", diff --git a/kubernetes/structures_pod.go b/kubernetes/structures_pod.go index 3bc7c00654..076f461adc 100644 --- a/kubernetes/structures_pod.go +++ b/kubernetes/structures_pod.go @@ -212,6 +212,9 @@ func flattenPodSecurityContext(in *v1.PodSecurityContext) []interface{} { if in.SeccompProfile != nil { att["seccomp_profile"] = flattenSeccompProfile(in.SeccompProfile) } + if in.FSGroupChangePolicy != nil { + att["fs_group_change_policy"] = *in.FSGroupChangePolicy + } if len(in.SupplementalGroups) > 0 { att["supplemental_groups"] = newInt64Set(schema.HashSchema(&schema.Schema{ Type: schema.TypeInt, @@ -898,7 +901,10 @@ func expandPodSecurityContext(l []interface{}) (*v1.PodSecurityContext, error) { if v, ok := in["sysctl"].([]interface{}); ok && len(v) > 0 { obj.Sysctls = expandSysctls(v) } - + if v, ok := in["fs_group_change_policy"].(string); ok && v != "" { + policy := v1.PodFSGroupChangePolicy(v) + obj.FSGroupChangePolicy = &policy + } return obj, nil } diff --git a/website/docs/d/pod.html.markdown b/website/docs/d/pod.html.markdown index 6349eddbb0..a3475eb4f3 100644 --- a/website/docs/d/pod.html.markdown +++ b/website/docs/d/pod.html.markdown @@ -384,6 +384,7 @@ The `items` block supports the following: * `run_as_user` - The UID to run the entrypoint of the container process. Defaults to user specified in image metadata if unspecified. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. * `seccomp_profile` - The seccomp options to use by the containers in this pod. Note that this field cannot be set when spec.os.name is windows. * `se_linux_options` - The SELinux context to be applied to the container. If unspecified, the container runtime will allocate a random SELinux context for each container. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. +* `fs_group_change_policy` - Defines behavior of changing ownership and permission of the volume before being exposed inside Pod. This field will only apply to volume types which support fsGroup based ownership(and permissions). It will have no effect on ephemeral volume types such as: secret, configmaps and emptydir. Valid values are "OnRootMismatch" and "Always". If not specified, "Always" is used. Note that this field cannot be set when spec.os.name is windows. ### `capabilities` diff --git a/website/docs/r/daemonset.html.markdown b/website/docs/r/daemonset.html.markdown index 67a6fdbcf1..fa684c0c12 100644 --- a/website/docs/r/daemonset.html.markdown +++ b/website/docs/r/daemonset.html.markdown @@ -725,6 +725,7 @@ The `items` block supports the following: * `run_as_user` - (Optional) The UID to run the entrypoint of the container process. Defaults to user specified in image metadata if unspecified. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. * `seccomp_profile` - The seccomp options to use by the containers in this pod. Note that this field cannot be set when spec.os.name is windows. * `se_linux_options` - (Optional) The SELinux context to be applied to the container. If unspecified, the container runtime will allocate a random SELinux context for each container. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. +* `fs_group_change_policy` - Defines behavior of changing ownership and permission of the volume before being exposed inside Pod. This field will only apply to volume types which support fsGroup based ownership(and permissions). It will have no effect on ephemeral volume types such as: secret, configmaps and emptydir. Valid values are "OnRootMismatch" and "Always". If not specified, "Always" is used. Note that this field cannot be set when spec.os.name is windows. ### `capabilities` diff --git a/website/docs/r/deployment.html.markdown b/website/docs/r/deployment.html.markdown index a2e6f241f0..c872ab4c4f 100644 --- a/website/docs/r/deployment.html.markdown +++ b/website/docs/r/deployment.html.markdown @@ -737,6 +737,7 @@ The `items` block supports the following: * `run_as_user` - (Optional) The UID to run the entrypoint of the container process. Defaults to user specified in image metadata if unspecified. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. * `seccomp_profile` - The seccomp options to use by the containers in this pod. Note that this field cannot be set when spec.os.name is windows. * `se_linux_options` - (Optional) The SELinux context to be applied to the container. If unspecified, the container runtime will allocate a random SELinux context for each container. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. +* `fs_group_change_policy` - Defines behavior of changing ownership and permission of the volume before being exposed inside Pod. This field will only apply to volume types which support fsGroup based ownership(and permissions). It will have no effect on ephemeral volume types such as: secret, configmaps and emptydir. Valid values are "OnRootMismatch" and "Always". If not specified, "Always" is used. Note that this field cannot be set when spec.os.name is windows. ### `capabilities` diff --git a/website/docs/r/pod.html.markdown b/website/docs/r/pod.html.markdown index eb557a8859..0d1a420a18 100644 --- a/website/docs/r/pod.html.markdown +++ b/website/docs/r/pod.html.markdown @@ -787,6 +787,7 @@ The `items` block supports the following: * `seccomp_profile` - The seccomp options to use by the containers in this pod. Note that this field cannot be set when spec.os.name is windows. * `se_linux_options` - (Optional) The SELinux context to be applied to the container. If unspecified, the container runtime will allocate a random SELinux context for each container. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. * `sysctl` - (Optional) holds a list of namespaced sysctls used for the pod. see [Sysctl](#sysctl) block. See [official docs](https://kubernetes.io/docs/tasks/administer-cluster/sysctl-cluster/) for more details. +* `fs_group_change_policy` - Defines behavior of changing ownership and permission of the volume before being exposed inside Pod. This field will only apply to volume types which support fsGroup based ownership(and permissions). It will have no effect on ephemeral volume types such as: secret, configmaps and emptydir. Valid values are "OnRootMismatch" and "Always". If not specified, "Always" is used. Note that this field cannot be set when spec.os.name is windows. ##### Sysctl