diff --git a/README.md b/README.md index a61c903ceca2a2fa6a5d1f5bd4b183af8b533473..8b0fd8f74250a651aebaa836a4116d07cdc089ed 100644 --- a/README.md +++ b/README.md @@ -322,6 +322,7 @@ The following environment variables are respected by the `gitlab-tofu` script: - `GITLAB_TOFU_AUTO_ENCRYPTION`: if set to true, enables auto state and plan encryption. Defaults to `false`. - `GITLAB_TOFU_AUTO_ENCRYPTION_PASSPHRASE`: the passphrase to use for state and plan encryption. Required if `GITLAB_TOFU_AUTO_ENCRYPTION` is true. - `GITLAB_TOFU_AUTO_ENCRYPTION_ENABLE_MIGRATION_FROM_UNENCRYPTED_ENABLED`: if set to true, enables a fallback for state and plan encryption to migrate unencrypted plans and states to encrypted ones. Defaults to `false`. +- `GITLAB_TOFU_ALLOW_DEVELOPER_ROLE: Users with the Developer role are not able to lock the state. Thus a regular `tofu plan` fails. When set to `true` a `-lock=false` is passed to plan. #### Respected OpenTofu Environment Variables diff --git a/src/gitlab-tofu.sh b/src/gitlab-tofu.sh index 4b98d618f4a3d9deba7cf0eaa8d0535797a34e18..408e43c2a4e4897d562ea90ee0771f849fdcba87 100644 --- a/src/gitlab-tofu.sh +++ b/src/gitlab-tofu.sh @@ -30,6 +30,7 @@ # - `GITLAB_TOFU_AUTO_ENCRYPTION`: if set to true, enables auto state and plan encryption. Defaults to `false`. # - `GITLAB_TOFU_AUTO_ENCRYPTION_PASSPHRASE`: the passphrase to use for state and plan encryption. Required if `GITLAB_TOFU_AUTO_ENCRYPTION` is true. # - `GITLAB_TOFU_AUTO_ENCRYPTION_ENABLE_MIGRATION_FROM_UNENCRYPTED_ENABLED`: if set to true, enables a fallback for state and plan encryption to migrate unencrypted plans and states to encrypted ones. Defaults to `false`. +# - `GITLAB_TOFU_ALLOW_DEVELOPER_ROLE: Users with the Developer role are not able to lock the state. Thus a regular `tofu plan` fails. When set to `true` a `-lock=false` is passed to plan. # # #### Respected OpenTofu Environment Variables # @@ -199,6 +200,7 @@ plan_jq_filter=' "delete":(map(select(.=="delete")) | length) } ' +allow_developer_role=${GITLAB_TOFU_ALLOW_DEVELOPER_ROLE:-false} # auto encryption related variables auto_encryption_enabled=${GITLAB_TOFU_AUTO_ENCRYPTION:-false} @@ -389,6 +391,9 @@ if [ $sourced -eq 0 ]; then if $plan_with_detailed_exitcode; then plan_args='-detailed-exitcode' fi + if $allow_developer_role; then + plan_args="$plan_args -lock=false" + fi $should_do_implicit_init && tofu_init # shellcheck disable=SC2086 diff --git a/templates/full-pipeline.yml b/templates/full-pipeline.yml index 4830ac373be14a71196d2a2249db5f30590c6171..0f4b27f44af2038de1987992579c7706ad0eb22d 100644 --- a/templates/full-pipeline.yml +++ b/templates/full-pipeline.yml @@ -201,6 +201,10 @@ spec: default: false type: boolean description: 'Whether to setup automatic state and plan encryption for currently unencrypted state. This is only temporarily useful when migrating from an unencrypted state.' + allow_developer_role_to_plan: + default: false + type: boolean + description: 'Users with the Developer role are not able to lock the state. Thus a regular `tofu plan` fails. When set to `true` a `-lock=false` is passed to plan.' --- @@ -284,6 +288,7 @@ include: auto_encryption: $[[ inputs.auto_encryption ]] auto_encryption_passphrase: $[[ inputs.auto_encryption_passphrase ]] auto_encryption_enable_migration_from_unencrypted: $[[ inputs.auto_encryption_enable_migration_from_unencrypted ]] + allow_developer_role: $[[ inputs.allow_developer_role_to_plan ]] - local: '/templates/apply.yml' rules: - if: '"$[[ inputs.trigger_in_child_pipeline ]]" == "false"' @@ -409,6 +414,7 @@ stages: auto_encryption: $[[ inputs.auto_encryption ]] auto_encryption_passphrase: $[[ inputs.auto_encryption_passphrase ]] auto_encryption_enable_migration_from_unencrypted: $[[ inputs.auto_encryption_enable_migration_from_unencrypted ]] + allow_developer_role_to_plan: $[[ inputs.allow_developer_role_to_plan ]] trigger_in_child_pipeline: false forward: yaml_variables: true diff --git a/templates/job-templates.yml b/templates/job-templates.yml index 5657e959f72e3d4d62f40ef1f0edf96a0d6648ae..b64ecd4a599e633ee1801e45767052f413491617 100644 --- a/templates/job-templates.yml +++ b/templates/job-templates.yml @@ -106,6 +106,10 @@ spec: default: false type: boolean description: 'Whether to setup automatic state and plan encryption for currently unencrypted state. This is only temporarily useful when migrating from an unencrypted state.' + allow_developer_role_to_plan: + default: false + type: boolean + description: 'Users with the Developer role are not able to lock the state. Thus a regular `tofu plan` fails. When set to `true` a `-lock=false` is passed to plan.' --- @@ -185,6 +189,7 @@ include: auto_encryption: $[[ inputs.auto_encryption ]] auto_encryption_passphrase: $[[ inputs.auto_encryption_passphrase ]] auto_encryption_enable_migration_from_unencrypted: $[[ inputs.auto_encryption_enable_migration_from_unencrypted ]] + allow_developer_role: $[[ inputs.allow_developer_role_to_plan ]] - local: '/templates/apply.yml' inputs: as: '$[[ inputs.job_name_prefix ]]apply' diff --git a/templates/plan.yml b/templates/plan.yml index 02461eea9ca6b22c1699375f97775a84361ebd52..69dae9552cf5686951750f45e55ebf6131e0fe9b 100644 --- a/templates/plan.yml +++ b/templates/plan.yml @@ -112,6 +112,10 @@ spec: default: false type: boolean description: 'Whether to setup automatic state and plan encryption for currently unencrypted state. This is only temporarily useful when migrating from an unencrypted state.' + allow_developer_role: + default: false + type: boolean + description: 'Users with the Developer role are not able to lock the state. Thus a regular `tofu plan` fails. When set to `true` a `-lock=false` is passed to plan.' --- @@ -177,6 +181,7 @@ spec: GITLAB_TOFU_AUTO_ENCRYPTION: '$[[ inputs.auto_encryption ]]' GITLAB_TOFU_AUTO_ENCRYPTION_PASSPHRASE: '$[[ inputs.auto_encryption_passphrase ]]' GITLAB_TOFU_AUTO_ENCRYPTION_ENABLE_MIGRATION_FROM_UNENCRYPTED: '$[[ inputs.auto_encryption_enable_migration_from_unencrypted ]]' + GITLAB_TOFU_ALLOW_DEVELOPER_ROLE: '$[[ inputs.allow_developer_role ]]' image: name: '$[[ inputs.image_registry_base ]]/$[[ inputs.image_name ]]:$[[ inputs.version ]]-opentofu$[[ inputs.opentofu_version ]]-$[[ inputs.base_os ]]$[[ inputs.image_digest ]]' script: diff --git a/templates/validate-plan-apply.yml b/templates/validate-plan-apply.yml index a643819de7464a402d1f815ad753b8841895fcff..b89116f3e3e823da6b880ce70c3cb361ba1ee86f 100644 --- a/templates/validate-plan-apply.yml +++ b/templates/validate-plan-apply.yml @@ -165,6 +165,10 @@ spec: default: false type: boolean description: 'Whether to setup automatic state and plan encryption for currently unencrypted state. This is only temporarily useful when migrating from an unencrypted state.' + allow_developer_role_to_plan: + default: false + type: boolean + description: 'Users with the Developer role are not able to lock the state. Thus a regular `tofu plan` fails. When set to `true` a `-lock=false` is passed to plan.' --- @@ -227,6 +231,7 @@ include: auto_encryption: $[[ inputs.auto_encryption ]] auto_encryption_passphrase: $[[ inputs.auto_encryption_passphrase ]] auto_encryption_enable_migration_from_unencrypted: $[[ inputs.auto_encryption_enable_migration_from_unencrypted ]] + allow_developer_role: $[[ inputs.allow_developer_role_to_plan ]] - local: '/templates/apply.yml' rules: - if: '"$[[ inputs.trigger_in_child_pipeline ]]" == "false"' @@ -304,6 +309,7 @@ stages: auto_encryption: $[[ inputs.auto_encryption ]] auto_encryption_passphrase: $[[ inputs.auto_encryption_passphrase ]] auto_encryption_enable_migration_from_unencrypted: $[[ inputs.auto_encryption_enable_migration_from_unencrypted ]] + allow_developer_role_to_plan: $[[ inputs.allow_developer_role_to_plan ]] trigger_in_child_pipeline: false forward: yaml_variables: true diff --git a/templates/validate-plan-destroy.yml b/templates/validate-plan-destroy.yml index 76f942e33717c351582814f4f1a2cf66c40ad7f7..5fc8a720faf228badc58953182f431c322cbceca 100644 --- a/templates/validate-plan-destroy.yml +++ b/templates/validate-plan-destroy.yml @@ -171,6 +171,10 @@ spec: default: false type: boolean description: 'Whether to setup automatic state and plan encryption for currently unencrypted state. This is only temporarily useful when migrating from an unencrypted state.' + allow_developer_role_to_plan: + default: false + type: boolean + description: 'Users with the Developer role are not able to lock the state. Thus a regular `tofu plan` fails. When set to `true` a `-lock=false` is passed to plan.' --- @@ -234,6 +238,7 @@ include: auto_encryption: $[[ inputs.auto_encryption ]] auto_encryption_passphrase: $[[ inputs.auto_encryption_passphrase ]] auto_encryption_enable_migration_from_unencrypted: $[[ inputs.auto_encryption_enable_migration_from_unencrypted ]] + allow_developer_role: $[[ inputs.allow_developer_role_to_plan ]] - local: '/templates/destroy.yml' rules: - if: '"$[[ inputs.trigger_in_child_pipeline ]]" == "false"' @@ -337,6 +342,7 @@ stages: auto_encryption: $[[ inputs.auto_encryption ]] auto_encryption_passphrase: $[[ inputs.auto_encryption_passphrase ]] auto_encryption_enable_migration_from_unencrypted: $[[ inputs.auto_encryption_enable_migration_from_unencrypted ]] + allow_developer_role_to_plan: $[[ inputs.allow_developer_role_to_plan ]] trigger_in_child_pipeline: false forward: yaml_variables: true diff --git a/templates/validate-plan.yml b/templates/validate-plan.yml index 99fd4652bf6673802617529a7a663831e15bf274..8262da9c6d010d2d29211b2c14ec788834f65b61 100644 --- a/templates/validate-plan.yml +++ b/templates/validate-plan.yml @@ -149,6 +149,10 @@ spec: default: false type: boolean description: 'Whether to setup automatic state and plan encryption for currently unencrypted state. This is only temporarily useful when migrating from an unencrypted state.' + allow_developer_role_to_plan: + default: false + type: boolean + description: 'Users with the Developer role are not able to lock the state. Thus a regular `tofu plan` fails. When set to `true` a `-lock=false` is passed to plan.' --- @@ -211,6 +215,7 @@ include: auto_encryption: $[[ inputs.auto_encryption ]] auto_encryption_passphrase: $[[ inputs.auto_encryption_passphrase ]] auto_encryption_enable_migration_from_unencrypted: $[[ inputs.auto_encryption_enable_migration_from_unencrypted ]] + allow_developer_role: $[[ inputs.allow_developer_role_to_plan ]] # NOTE: the following configuration is only used if `trigger_in_child_pipeline` is enabled. @@ -264,6 +269,7 @@ stages: auto_encryption: $[[ inputs.auto_encryption ]] auto_encryption_passphrase: $[[ inputs.auto_encryption_passphrase ]] auto_encryption_enable_migration_from_unencrypted: $[[ inputs.auto_encryption_enable_migration_from_unencrypted ]] + allow_developer_role_to_plan: $[[ inputs.allow_developer_role_to_plan ]] trigger_in_child_pipeline: false forward: yaml_variables: true