保存状态时出错:无法上载状态:POST



我有Gitlab CICD管道来部署我的地形更改,它使用Gitlabhttp后端来存储状态文件。但是,由于以下错误,它暂时无法保存状态文件。

错误发生在创建资源之后,因此重新运行同一作业有时可以解决问题,但会复制资源。

这个错误的原因可能是什么?

gitlab-ci.yml:

variables:
TF_ROOT: ${CI_PROJECT_DIR}
TF_ADDRESS: ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/terraform/state/${CI_PROJECT_NAME}
TF_VAR_app_key: ${APP_KEY}
TF_VAR_api_key: ${API_KEY}
TF_VAR_gitlab_token: ${CI_JOB_TOKEN}
TF_VAR_environment: ${ENV}
TF_CLI_CONFIG_FILE: $CI_PROJECT_DIR/.terraformrc
default:
image: registry.gitlab.com/gitlab-org/terraform-images/stable:latest
cache:
key: ${CI_PROJECT_NAME}
paths:
- ${TF_ROOT}/.terraform

before_script:
- echo -e "credentials "$CI_SERVER_HOST" {n  token = "$CI_JOB_TOKEN"n}" > $TF_CLI_CONFIG_FILE
- cd ${TF_ROOT}
stages:
- prepare
- validate
- build
- deploy
init:
stage: prepare
script:
- gitlab-terraform -v
- gitlab-terraform init
validate:
stage: validate
script:
- gitlab-terraform validate
plan:
stage: build
script:
- gitlab-terraform plan
- gitlab-terraform plan-json
artifacts:
name: plan
paths:
- ${TF_ROOT}/plan.cache
reports:
terraform: ${TF_ROOT}/plan.json
rules:
- if: $CI_COMMIT_REF_NAME == "main" 
when: on_success
apply:
stage: deploy
environment:
name: $TF_VAR_environment
script:
- gitlab-terraform apply --auto-approve
dependencies:
- plan
artifacts:
name: errored_tfstate
paths:
- ${TF_ROOT}/errored.tfstate
when: on_failure
rules:
- if: $CI_COMMIT_REF_NAME == "main" 
when: manual
allow_failure: false

作业输出:

...
If you'd like to know more about provider signing, you can read about it here:
https://www.terraform.io/docs/cli/plugins/signing.html
Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.
Terraform has been successfully initialized!
2021/11/07 13:14:21 [DEBUG] POST https://gitlab.operations.mcorg.com/api/v4/projects/16/terraform/state/resources/lock
2021/11/07 13:14:21 [DEBUG] GET https://gitlab.operations.mcorg.com/api/v4/projects/16/terraform/state/resources
module....: Creating...
...
...
2021/11/07 13:14:23 [DEBUG] GET https://gitlab.operations.mcorg.com/api/v4/projects/16/terraform/state/resources
2021/11/07 13:14:23 [DEBUG] POST https://gitlab.operations.mcorg.com/api/v4/projects/16/terraform/state/resources?ID=cc520c4e-21c1-b787-46bf-5b577a9bf594
2021/11/07 13:14:23 [DEBUG] POST https://gitlab.operations.mcorg.com/api/v4/projects/16/terraform/state/resources?ID=cc520c4e-21c1-b787-46bf-5b577a9bf594 (status: 500): retrying in 5s (2 left)
2021/11/07 13:14:29 [DEBUG] POST https://gitlab.operations.mcorg.com/api/v4/projects/16/terraform/state/resources?ID=cc520c4e-21c1-b787-46bf-5b577a9bf594 (status: 500): retrying in 10s (1 left)
╷
│ Error: Failed to save state
│ 
│ Error saving state: Failed to upload state: POST
│ https://gitlab.operations.mcorg.com/api/v4/projects/16/terraform/state/resources?ID=cc520c4e-21c1-b787-46bf-5b577a9bf594
│ giving up after 3 attempts
╵
╷
│ Error: Failed to persist state to backend
│ 
│ The error shown above has prevented Terraform from writing the updated
│ state to the configured backend. To allow for recovery, the state has been
│ written to the file "errored.tfstate" in the current working directory.
│ 
│ Running "terraform apply" again at this point will create a forked state,
│ making it harder to recover.
│ 
│ To retry writing this state, use the following command:
│     terraform state push errored.tfstate
│ 
╵
2021/11/07 13:14:40 [DEBUG] DELETE https://gitlab.operations.mcorg.com/api/v4/projects/16/terraform/state/resources/lock
...
Uploading artifacts as "archive" to coordinator... ok  id=248 responseStatus=201 Created token=****
Cleaning up file based variables
00:00
ERROR: Job failed: command terminated with exit code 1

我面临一个不同的问题,但与您的问题相同。

╷
│ Error: Failed to save state
│ 
│ Error saving state: HTTP error: 403
╵
╷
│ Error: Failed to persist state to backend
│ 
│ The error shown above has prevented Terraform from writing the updated
│ state to the configured backend. To allow for recovery, the state has been
│ written to the file "errored.tfstate" in the current working directory.
│ 
│ Running "terraform apply" again at this point will create a forked state,
│ making it harder to recover.
│ 
│ To retry writing this state, use the following command:
│     terraform state push errored.tfstate
│ 
╵
Uploading artifacts for failed job

将权限(在项目中(更改为开发人员以上的任何人

在我的情况下,我将其更改为Maintainer或更高版本,并且运行良好。