Gitlab - 从部署中分离 CI
Gitlab - Separating CI from Deployment
我们目前正在使用 Jenkins,并计划迁移到 Gitlab。我们实际上在每个 repo 中有 2 个 Jenkinsfiles,其中 1 个设置为 Multib运行ch 管道和 运行s 用于所有更改。它是合并检查,运行 所有各种检查、测试、构建 docker 容器等。第二个 Jenkinsfile 只是 运行 来自 Jenkins 的手动,它包含所有各种输入参数并部署代码。这主要来自说,linted Ansible/Terraform 并选择一个 docker 已经通过 CI 方面构建的图像。
我知道 gitlab 不支持这个模型,但是这个项目已经是 MVP,所以重新设计开发人员如何将他们的逻辑和部署代码组合在一起可能不会发生。
是否可能,在 1 个 gitlab-ci.yml 文件中说 run these jobs on merge/pushes
而只有 运行 this on manual deployment
.
例如
workflow:
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
- if: '$CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS'
when: never
- if: '$CI_COMMIT_BRANCH'
stages:
- test
- test
- deploy
- destroy
test-python-job:
stage: test
rules:
- if: '$CI_PIPELINE_SOURCE == "push"'
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
script:
- echo "Test Python"
- black
- bandit
- flake8
- tox
test-terraform-job:
stage: test
rules:
- if: '$CI_PIPELINE_SOURCE == "push"'
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
script:
- echo "Test Terraform"
- terraform validate --yadda
test-ansible-job:
stage: test
rules:
- if: '$CI_PIPELINE_SOURCE == "push"'
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
script:
- echo "Test Ansible"
- ansible-lint --yadda
deploy-job:
stage: deploy
variables:
DEPLOYMENT_ID: "Only deploy-job can use this variable's value"
secrets:
DATABASE_PASSWORD:
vault: production/db/password@ops
rules:
- when: manual
script:
- echo "Terraform Deploy"
- terraform deploy
- ansible-playbook yaddas
destroy-job:
stage: destroy
variables:
DEPLOYMENT_ID: "Only destroy-job can use this variable's value"
secrets:
DATABASE_PASSWORD:
vault: production/db/password@ops
rules:
- when: manual
script:
- terraform destroy
我们甚至还没有部署 gitlab,所以我想把它写下来,但我想知道我的痛苦程度。
有多种选择可以以最少的配置工作实现您的目标:
- 处理私有作业并使用继承或引用来简化配置 - 可在一个文件中完成
- 将部件提取到子管道中以便于使用
在一个文件中减少配置
我想您最讨厌必须重新定义工作规则。有两种方法可以减少这些重复。
继承
可以减少大量重复,但也可能导致问题,产生意想不到的副作用。
.test:
stage: test
rules:
- if: '$CI_PIPELINE_SOURCE == "push"'
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
test-python-job:
extends: .test
script:
- echo "Test Python"
- black
- bandit
- flake8
- tox
test-terraform-job:
extends: .test
script:
- echo "Test Terraform"
- terraform validate --yadda
test-ansible-job:
extends: .test
script:
- echo "Test Ansible"
- ansible-lint --yadda
作文
通过使用 !reference
,您可以结合工作的某些方面,请参阅 https://docs.gitlab.com/ee/ci/yaml/#reference-tags
.test:
rules:
- if: '$CI_PIPELINE_SOURCE == "push"'
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
test-python-job:
stage: test
rules:
- !reference [.test, rules]
script:
- echo "Test Python"
- black
- bandit
- flake8
- tox
test-terraform-job:
stage: test
rules:
- !reference [.test, rules]
script:
- echo "Test Terraform"
- terraform validate --yadda
stage: test
rules:
- !reference [.test, rules]
script:
- echo "Test Ansible"
- ansible-lint --yadda
父子管道
有时也可以将功能提取到子管道中。当您调用子管道并由于更少的代码行而获得概览时,您可以更轻松地控制一个阶段发生的事情。它增加了构建的复杂性。但通常它会生成一个更清洁、更易于维护的 ci 结构(我的意见)。
此方法只会在需要时添加子管道 - 此外,如果部署与此类似,您还可以集中此文件
.gitlab-ci.yml
deploy:
stage: deploy
trigger:
include:
- local: Deploy.gitlab-ci.yml
strategy: depend
rules:
- if: $CI_PIPELINE_SOURCE == 'web' #maybe also useful, as it will only happen on a web interaction
when: manual
- if: $CI_PIPELINE_SOURCE == 'schedule' #maybe also useful, for schedules
Deploy.gitlab-ci.yml
deploy-job:
stage: deploy
variables:
DEPLOYMENT_ID: "Only deploy-job can use this variable's value"
secrets:
DATABASE_PASSWORD:
vault: production/db/password@ops
script:
- echo "Terraform Deploy"
- terraform deploy
- ansible-playbook yaddas
destroy-job:
stage: destroy
variables:
DEPLOYMENT_ID: "Only destroy-job can use this variable's value"
secrets:
DATABASE_PASSWORD:
vault: production/db/password@ops
script:
- terraform destroy
旁注
这不是 100% 回答你的问题,但它向你展示了很大的灵活性,你很快就会意识到模仿 jenkins 并不是 100% 理想的。例如,将部署作业直接附加到提交上,并在提交上可见,这样可以更好地了解确切部署的内容。如果您需要手动 运行 此类内容,我强烈建议您使用具有预配置值的时间表,因为它们只有一个播放按钮。此外,您已经准备好工件并从您的管道构建,为什么不添加额外的步骤来利用它们,而不是提供此信息
希望我的见解对您有用,祝您迁移愉快;)
我们目前正在使用 Jenkins,并计划迁移到 Gitlab。我们实际上在每个 repo 中有 2 个 Jenkinsfiles,其中 1 个设置为 Multib运行ch 管道和 运行s 用于所有更改。它是合并检查,运行 所有各种检查、测试、构建 docker 容器等。第二个 Jenkinsfile 只是 运行 来自 Jenkins 的手动,它包含所有各种输入参数并部署代码。这主要来自说,linted Ansible/Terraform 并选择一个 docker 已经通过 CI 方面构建的图像。
我知道 gitlab 不支持这个模型,但是这个项目已经是 MVP,所以重新设计开发人员如何将他们的逻辑和部署代码组合在一起可能不会发生。
是否可能,在 1 个 gitlab-ci.yml 文件中说 run these jobs on merge/pushes
而只有 运行 this on manual deployment
.
例如
workflow:
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
- if: '$CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS'
when: never
- if: '$CI_COMMIT_BRANCH'
stages:
- test
- test
- deploy
- destroy
test-python-job:
stage: test
rules:
- if: '$CI_PIPELINE_SOURCE == "push"'
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
script:
- echo "Test Python"
- black
- bandit
- flake8
- tox
test-terraform-job:
stage: test
rules:
- if: '$CI_PIPELINE_SOURCE == "push"'
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
script:
- echo "Test Terraform"
- terraform validate --yadda
test-ansible-job:
stage: test
rules:
- if: '$CI_PIPELINE_SOURCE == "push"'
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
script:
- echo "Test Ansible"
- ansible-lint --yadda
deploy-job:
stage: deploy
variables:
DEPLOYMENT_ID: "Only deploy-job can use this variable's value"
secrets:
DATABASE_PASSWORD:
vault: production/db/password@ops
rules:
- when: manual
script:
- echo "Terraform Deploy"
- terraform deploy
- ansible-playbook yaddas
destroy-job:
stage: destroy
variables:
DEPLOYMENT_ID: "Only destroy-job can use this variable's value"
secrets:
DATABASE_PASSWORD:
vault: production/db/password@ops
rules:
- when: manual
script:
- terraform destroy
我们甚至还没有部署 gitlab,所以我想把它写下来,但我想知道我的痛苦程度。
有多种选择可以以最少的配置工作实现您的目标:
- 处理私有作业并使用继承或引用来简化配置 - 可在一个文件中完成
- 将部件提取到子管道中以便于使用
在一个文件中减少配置
我想您最讨厌必须重新定义工作规则。有两种方法可以减少这些重复。
继承
可以减少大量重复,但也可能导致问题,产生意想不到的副作用。
.test:
stage: test
rules:
- if: '$CI_PIPELINE_SOURCE == "push"'
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
test-python-job:
extends: .test
script:
- echo "Test Python"
- black
- bandit
- flake8
- tox
test-terraform-job:
extends: .test
script:
- echo "Test Terraform"
- terraform validate --yadda
test-ansible-job:
extends: .test
script:
- echo "Test Ansible"
- ansible-lint --yadda
作文
通过使用 !reference
,您可以结合工作的某些方面,请参阅 https://docs.gitlab.com/ee/ci/yaml/#reference-tags
.test:
rules:
- if: '$CI_PIPELINE_SOURCE == "push"'
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
test-python-job:
stage: test
rules:
- !reference [.test, rules]
script:
- echo "Test Python"
- black
- bandit
- flake8
- tox
test-terraform-job:
stage: test
rules:
- !reference [.test, rules]
script:
- echo "Test Terraform"
- terraform validate --yadda
stage: test
rules:
- !reference [.test, rules]
script:
- echo "Test Ansible"
- ansible-lint --yadda
父子管道
有时也可以将功能提取到子管道中。当您调用子管道并由于更少的代码行而获得概览时,您可以更轻松地控制一个阶段发生的事情。它增加了构建的复杂性。但通常它会生成一个更清洁、更易于维护的 ci 结构(我的意见)。
此方法只会在需要时添加子管道 - 此外,如果部署与此类似,您还可以集中此文件
.gitlab-ci.yml
deploy:
stage: deploy
trigger:
include:
- local: Deploy.gitlab-ci.yml
strategy: depend
rules:
- if: $CI_PIPELINE_SOURCE == 'web' #maybe also useful, as it will only happen on a web interaction
when: manual
- if: $CI_PIPELINE_SOURCE == 'schedule' #maybe also useful, for schedules
Deploy.gitlab-ci.yml
deploy-job:
stage: deploy
variables:
DEPLOYMENT_ID: "Only deploy-job can use this variable's value"
secrets:
DATABASE_PASSWORD:
vault: production/db/password@ops
script:
- echo "Terraform Deploy"
- terraform deploy
- ansible-playbook yaddas
destroy-job:
stage: destroy
variables:
DEPLOYMENT_ID: "Only destroy-job can use this variable's value"
secrets:
DATABASE_PASSWORD:
vault: production/db/password@ops
script:
- terraform destroy
旁注
这不是 100% 回答你的问题,但它向你展示了很大的灵活性,你很快就会意识到模仿 jenkins 并不是 100% 理想的。例如,将部署作业直接附加到提交上,并在提交上可见,这样可以更好地了解确切部署的内容。如果您需要手动 运行 此类内容,我强烈建议您使用具有预配置值的时间表,因为它们只有一个播放按钮。此外,您已经准备好工件并从您的管道构建,为什么不添加额外的步骤来利用它们,而不是提供此信息
希望我的见解对您有用,祝您迁移愉快;)