我终于成功运行了设置。我的解决方案使用AWS Route53进行动态主机名生成(一个我忽略太久的问题 - 我需要为不同的审查应用程序获取主机名)。
步骤1:
动态构建主机名。为此,我使用了
$CI_PIPELINE_ID
。我在Route53上创建了一个子域,我们称之为
review.mydomain.com
。Ansible Playbook从create_droplet中获取IP地址,并在Route53上创建一个记录,其中包含Pipeline ID。
1234.review.mydomain.com
。
现在我的.gitlab-ci.yml知道这个主机名(因为它可以随时构建它)-不再需要从ansible脚本中获取Digitalocean droplet IP。
步骤2:
审核后,用户应能够停止/销毁droplet。为此,我需要在创建此droplet时获取droplet id。但销毁是一个不同的playbook,稍后将由开发人员调用。
因此,我需要在某个地方存储变量。
但是等等,现在我知道了它是哪个主机,我只需在此主机上创建一个事实文件,为我存储ID。当我需要销毁主机时,ansible会为我提供这些事实,并且我知道ID。
在playbook中,它看起来像这样:
角色:digitalocean
---
- name: Create DO Droplet
delegate_to: localhost
local_action:
module: digital_ocean
state=present
command=droplet
name=oewm-review-{{ do_name }}
api_token={{ do_token }}
region_id={{ do_region }}
image_id={{ do_image }}
size_id={{ do_size }}
ssh_key_ids={{ do_ssh }}
wait_timeout=500
register: my_droplet
- name: print info about droplet
delegate_to: localhost
local_action:
module: debug
msg="DO-ID:{{ my_droplet.droplet.id }}"
- name: print info about droplet
delegate_to: localhost
local_action:
module: debug
msg="DO-IP:{{ my_droplet.droplet.ip_address }}"
- name: Get existing host information
route53:
command: get
zone: "{{ r53_zone }}"
record: "{{ do_name }}.review.mydomain.com"
type: A
aws_access_key: "{{ r53_access_key }}"
aws_secret_key: "{{ r53_secret_key }}"
register: currentip
- name: Add DNS Record for Web-Application
route53:
command: create
zone: "{{ r53_zone }}"
record: "{{ do_name }}.review.mydomain.com"
type: A
ttl: 600
value: "{{ my_droplet.droplet.ip_address }}"
aws_access_key: "{{ r53_access_key }}"
aws_secret_key: "{{ r53_secret_key }}"
when: currentip.set.value is not defined
- name: Add DNS Record for API
route53:
command: create
zone: "{{ r53_zone }}"
record: "api.{{ do_name }}.review.mydomain.com"
type: A
ttl: 600
value: "{{ my_droplet.droplet.ip_address }}"
aws_access_key: "{{ r53_access_key }}"
aws_secret_key: "{{ r53_secret_key }}"
when: currentip.set.value is not defined
- name: Add new droplet to host group
add_host:
hostname: "{{ my_droplet.droplet.ip_address }}"
groupname: api,web-application
ansible_user: root
api_domain: "api.{{ do_name }}.review.mydomain.com"
app_domain: "{{ do_name }}.review.mydomain.com"
- name: Wait until SSH is available on {{ my_droplet.droplet.ip_address }}
local_action:
module: wait_for
host: "{{ my_droplet.droplet.ip_address }}"
port: 22
delay: 5
timeout: 320
state: started
Playbook digitalocean.yml:
---
- name: Launch DO Droplet
hosts: all
run_once: true
gather_facts: false
roles:
- digitalocean
- name: Store Facts
hosts: api
tasks:
- name: Ensure facts directory exists
file:
path: "/etc/ansible/facts.d"
state: directory
- name: store variables on host for later fact gathering
template:
src={{ playbook_dir }}/roles/digitalocean/templates/digitalocean.fact.js2
dest="/etc/ansible/facts.d/digitalocean.fact"
mode=0644
- name: Deploy
hosts: api
roles:
- deployroles
Playbook digitalocean_destroy.yml:
- name: Add Host to Inventory
hosts: all
vars:
r53_zone: review.mydomain.com
r53_access_key: "xxxx"
r53_secret_key: "xxxx"
tasks:
- name: Get existing DNS host information
route53:
command: get
zone: "{{ r53_zone }}"
record: "{{ do_name }}.review.mydomain.com"
type: A
aws_access_key: "{{ r53_access_key }}"
aws_secret_key: "{{ r53_secret_key }}"
register: currentip
- name: Remove DNS Record for Web-Application
route53:
command: delete
zone: "{{ r53_zone }}"
record: "{{ do_name }}.review.mydomain.com"
type: A
ttl: 600
value: "{{ my_droplet.droplet.ip_address }}"
aws_access_key: "{{ r53_access_key }}"
aws_secret_key: "{{ r53_secret_key }}"
when: currentip.set.value is defined
- name: Remove DNS Record for API
route53:
command: delete
zone: "{{ r53_zone }}"
record: "api.{{ do_name }}.review.mydomain.com"
type: A
ttl: 600
value: "{{ my_droplet.droplet.ip_address }}"
aws_access_key: "{{ r53_access_key }}"
aws_secret_key: "{{ r53_secret_key }}"
when: currentip.set.value is defined
- name: Add droplet to host group
add_host:
hostname: "{{ do_name }}.review.mydomain.com"
groupname: api,web-application
ansible_user: root
- name: Digitalocean
hosts: api
vars:
do_token: xxxxx
tasks:
- name: Delete Droplet
delegate_to: localhost
local_action:
module: digital_ocean
state=deleted
command=droplet
api_token={{ do_token }}
id="{{ ansible_local.digitalocean.DO_ID }}"
.gitlab-ci.yml中相关部分:
Deploy for Review:
before_script: []
stage: review
script:
- 'cd /home/playbooks/myname/deployment && ansible-playbook -i inventories/review --extra-vars "do_name=$CI_PIPELINE_ID api_git_branch=$CI_BUILD_REF_NAME" digitalocean.yml'
environment:
name: review/$CI_BUILD_REF_NAME
url: http://$CI_PIPELINE_ID.review.mydomain.com
on_stop: "Stop Review"
only:
- branches
when: manual
tags:
- deploy
Stop Review:
before_script: []
stage: review
variables:
GIT_STRATEGY: none
script:
- 'cd /home/playbooks/myname/deployment && ansible-playbook -i inventories/review --extra-vars "do_name=$CI_PIPELINE_ID" digitalocean_destroy.yml'
when: manual
environment:
name: review/$CI_BUILD_REF_NAME
action: stop
only:
- branches
tags:
- deploy
Deploy to Staging:
before_script: []
stage: staging
script:
- 'cd /home/playbooks/myname/deployment && ansible-playbook -i inventories/staging --extra-vars "api_git_branch=$CI_BUILD_REF_NAME" deploy.yml'
environment:
name: staging
url: https://staging.mydomain.com
when: manual
tags:
- deploy