-
Notifications
You must be signed in to change notification settings - Fork 0
Description
Summary
When a value used in a semaphoreui_project_environment secret resource is changing (rotated through another terraform provider, in my case a gitlab access token), the terraform plan is seeing the semaphoreui_project_environment update for the specific secret entry but the entry value is not updated properly after apply.
Versions
Semaphore server : v2.16.34-87a1c53-1760097739
Semaphore provider : semaphoreui/semaphore v0.2.1
Terraform : v1.13.3
Terraform Tests
resource "gitlab_personal_access_token" "this" {
for_each = var.init_users_to_configure
user_id = local.gitlab_users[each.key].id
name = "${each.value.gitlab_user} personal access token"
scopes = ["api", "read_api"]
rotation_configuration = {
expiration_days = "365"
rotate_before_days = "15"
}
depends_on = [module.register_users]
}
...
resource "semaphoreui_project_environment" "this" {
for_each = local.semaphore_project_repositories
project_id = each.value.project_id
name = "${each.value.key}-repo${each.value.project_repository_id}-terraform-env-secrets"
secrets = [
{
name = "AWS_ACCESS_KEY_ID"
value = var.aws_access_key_id
type = "env"
},
{
name = "AWS_SECRET_ACCESS_KEY"
value = var.aws_secret_access_id
type = "env"
},
{
name = "GITLAB_TOKEN_ADMIN"
value = var.gitlab_token
type = "env"
},
{
name = "GITLAB_TOKEN_USER"
value = gitlab_personal_access_token.this[each.value.key].token
type = "env"
},
{
name = "SEMAPHORE_API_TOKEN"
value = var.semaphore_api_token
type = "env"
},
{
name = "VAULT_TOKEN"
value = var.vault_token
type = "env"
},
{
name = "VAULT_APPROLE_ROLE_ID"
value = module.register_users.approles_role_id[format("%s-%s", each.value.key, each.value.environment)]
type = "env"
},
{
name = "VAULT_APPROLE_SECRET_ID"
value = module.register_users.approles_secret_id[format("%s-%s", each.value.key, each.value.environment)]
type = "env"
},
{
# sshkeys also added in env secrets because of bash/ansible only use it for initial checkout
name = "SSH_KEYS_GITLAB"
value = module.register_users.user_gitlab_keys[each.value.key]
type = "env"
},
{
name = "SSH_KEYS_SERVER"
value = module.register_users.user_server_keys[format("%s-%s", each.value.key, each.value.environment)]
type = "env"
}
]
}
- Terraform plan apply
08:53:36.218 STDOUT terraform: Terraform will perform the following actions:
08:53:36.218 STDOUT terraform: # gitlab_personal_access_token.this["user-test"] will be updated in-place
08:53:36.218 STDOUT terraform: ~ resource "gitlab_personal_access_token" "this" {
08:53:36.218 STDOUT terraform: ~ active = true -> (known after apply)
08:53:36.218 STDOUT terraform: ~ created_at = "2025-10-28 08:43:57.007 +0000 UTC" -> (known after apply)
08:53:36.218 STDOUT terraform: ~ id = "330:324" -> (known after apply)
08:53:36.218 STDOUT terraform: name = "user-test-gitops personal access token"
08:53:36.218 STDOUT terraform: ~ revoked = false -> (known after apply)
08:53:36.218 STDOUT terraform: ~ rotation_configuration = {
08:53:36.218 STDOUT terraform: ~ rotate_before_days = 15 -> 10
08:53:36.218 STDOUT terraform: # (1 unchanged attribute hidden)
08:53:36.218 STDOUT terraform: }
08:53:36.218 STDOUT terraform: ~ token = (sensitive value)
08:53:36.218 STDOUT terraform: # (5 unchanged attributes hidden)
08:53:36.218 STDOUT terraform: }
08:53:36.218 STDOUT terraform: # semaphoreui_project_environment.this["user-test-0"] will be updated in-place
08:53:36.218 STDOUT terraform: ~ resource "semaphoreui_project_environment" "this" {
08:53:36.218 STDOUT terraform: id = 342
08:53:36.218 STDOUT terraform: name = "user-test-repo242-terraform-env-secrets"
08:53:36.218 STDOUT terraform: ~ secrets = [
08:53:36.218 STDOUT terraform: ~ {
08:53:36.218 STDOUT terraform: id = 1110
08:53:36.219 STDOUT terraform: name = "GITLAB_TOKEN_USER"
08:53:36.219 STDOUT terraform: ~ value = (sensitive value)
08:53:36.219 STDOUT terraform: # (1 unchanged attribute hidden)
08:53:36.219 STDOUT terraform: },
08:53:36.219 STDOUT terraform: # (9 unchanged elements hidden)
08:53:36.219 STDOUT terraform: ]
08:53:36.219 STDOUT terraform: # (1 unchanged attribute hidden)
08:53:36.219 STDOUT terraform: }
...
08:53:36.219 STDOUT terraform:
08:53:37.085 STDOUT terraform: gitlab_personal_access_token.this["user-test"]: Modifying... [id=330:324]
08:53:37.236 STDOUT terraform: gitlab_personal_access_token.this["user-test"]: Modifications complete after 0s [id=330:325]
08:53:37.433 STDOUT terraform: semaphoreui_project_environment.this["user-test-0"]: Modifying... [name=user-test-repo242-terraform-env-secrets]
08:53:37.616 STDOUT terraform: semaphoreui_project_environment.this["user-test-0"]: Modifications complete after 1s [name=user-test-repo242-terraform-env-secrets]
Expected Behavior
I was expecting the environment secret entry GITLAB_TOKEN_USER to be updated with the new gitlab token value but it's not.
The same secret update execute through the Semaphore API is working as expected
curl -X 'PUT' \
'https://semaphoreui-mysite.com/api/project/12/environment/134' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"id": 342,
"name": "user-repo242-terraform-env-secrets",
"project_id": 12,
"password": null,
"json": "{}",
"env": "{}",
"secrets": [
{
"id": 1110,
"name": "GITLAB_TOKEN_USER",
"secret": "glpat-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"type": "env",
"operation": "update"
}
]
}'
The env secret entry GITLAB_TOKEN_USER is well updated
More tests on the provider api calls
I'm not fluent in go and decided to intercept the provider API calls (using mitmproxy) to check the sent payload during that terraform environment secret update.
It seems that no secret values are sent in the JSON payload when the provider is trying to update an environment secret value.
PUT REQUEST
PUT /api/project/12/environment/134 HTTP/1.1
Host: semaphoreui-mysite.com:443
User-Agent: Go-http-client/1.1
Content-Length: 649
Accept: application/json
Accept: text/plain; charset=utf-8
Authorization: Bearer XxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXx=
Content-Type: application/json
Accept-Encoding: gzip{"env":"{}","id":134,"json":"{}","name":"user-repo23-terraform-env-secrets","project_id":12,"secrets":[{"id":514,"name":"AWS_ACCESS_KEY_ID","type":"env"},{"id":515,"name":"AWS_SECRET_ACCESS_KEY","type":"env"},{"id":51
6,"name":"GITLAB_TOKEN_ADMIN","type":"env"},{"id":517,"name":"GITLAB_TOKEN_USER","operation":"update","type":"env"},{"id":518,"name":"SEMAPHORE_API_TOKEN","type":"env"},{"id":519,"name":"VAULT_TOKEN","type":"env"},{"i
d":520,"name":"VAULT_APPROLE_ROLE_ID","type":"env"},{"id":521,"name":"VAULT_APPROLE_SECRET_ID","type":"env"},{"id":522,"name":"SSH_KEYS_GITLAB","type":"env"},{"id":523,"name":"SSH_KEYS_SERVER","type":"env"}]}
PUT RESPONSE
HTTP/1.1 204 No Content
Content-Type: application/json
Date: Fri, 24 Oct 2025 11:01:17 GMT
So I'm wondering is it intentional ?
in any case this is very annoying for the life cycle management of these secrets also stored in Semaphore environment secrets