gitlab - Gitlab - 从部署中分离 CI
问题描述
我们目前正在使用 Jenkins,并计划迁移到 Gitlab。我们实际上在每个 repo 中有 2 个 Jenkinsfiles,1 个设置为 Multibranch 管道并在所有更改上运行。它是合并检查,运行所有各种 linting、测试、构建 docker 容器等。第二个 Jenkinsfile 仅从 Jenkins 手动运行,它接受所有各种输入参数并部署代码。这主要来自于 linted Ansible/Terraform 并选择了一个已经通过 CI 方面构建的 docker 镜像。
我知道 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
部署.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% 理想的。例如,将部署作业直接附加到提交并在该提交上可见,可以更好地了解确切部署的内容。如果您需要手动运行这些东西,我强烈建议您使用具有预配置值的时间表,因为它们只有一个播放按钮。此外,您已经有了工件并从您的管道构建,为什么不添加使用它们的额外步骤,而不是提供此信息
我希望我的见解对您有用,祝您迁移愉快;)
推荐阅读
- javascript - Vue-i18n 和列表
- vision - Automl 图像预测问题
- python - 为什么我无法使用 BeautifulSoup 从网站获取数据?我收到超时错误
- java - jboss 错误:java.lang.NoSuchMethodError:org.hibernate.internal.CoreMessageLogger.debugf(Ljava/lang/String;I)V
- r - R Shiny:如何暂时禁用反应性?
- .net - 序列化时动态命名属性
- java - IBM MQ 获取按通道名称分组的连接计数
- blueprism - Blueprism 舍入问题
- c# - 使用 if 语句选择了错误的条件
- python - 设计一个神经网络来预测 Keras 中的数字数组