下面是一个自动化部署SSL证书的Ansible Playbook示例,涵盖从本地分发证书到远程服务器并配置Nginx的过程。该Playbook考虑了文件权限、目录创建、配置模板和服务重载。同时提供了扩展思路,如集成Let's Encrypt自动获取证书。
yaml
name: 自动化部署SSL证书到Web服务器
hosts: webservers
become: yes
vars:
# 证书文件路径(远程服务器上的目标位置)
ssl_cert_path: /etc/ssl/certs/{{ ansible_host }}.crt
ssl_key_path: /etc/ssl/private/{{ ansible_host }}.key
ssl_chain_path: /etc/ssl/certs/{{ ansible_host }}-chain.pem # 可选,证书链
# 服务相关
service_name: nginx
nginx_config_dir: /etc/nginx/sites-available
nginx_enabled_dir: /etc/nginx/sites-enabled
site_config_file: "{{ ansible_host }}.conf"
tasks:
- name: 确保SSL证书目录存在且权限正确
file:
path: "{{ item }}"
state: directory
mode: 0755
loop:
- /etc/ssl/certs
- /etc/ssl/private
- name: 复制SSL证书文件
copy:
src: "files/{{ ansible_host }}.crt" # 本地相对路径,可调整
dest: "{{ ssl_cert_path }}"
mode: 0644
notify: reload nginx
- name: 复制SSL私钥文件
copy:
src: "files/{{ ansible_host }}.key"
dest: "{{ ssl_key_path }}"
mode: 0600 # 私钥必须严格权限
notify: reload nginx
# 敏感文件建议用Ansible Vault加密存储
- name: 复制CA证书链(如有)
copy:
src: "files/{{ ansible_host }}-chain.pem"
dest: "{{ ssl_chain_path }}"
mode: 0644
when: ssl_chain_path is defined
notify: reload nginx
- name: 部署Nginx站点配置文件(使用SSL配置模板)
template:
src: nginx_ssl.conf.j2
dest: "{{ nginx_config_dir }}/{{ site_config_file }}"
mode: 0644
notify: reload nginx
- name: 启用站点配置(创建符号链接)
file:
src: "{{ nginx_config_dir }}/{{ site_config_file }}"
dest: "{{ nginx_enabled_dir }}/{{ site_config_file }}"
state: link
notify: reload nginx
handlers:
- name: reload nginx
systemd:
name: nginx
state: reloaded
说明与扩展
1. 基本逻辑
文件分发:将本地预置的证书文件(`.crt`、`.key`、`.pem`)复制到远程服务器的标准位置,并设置正确的权限(证书公开可读,私钥仅root可读写)。
配置更新:通过Jinja2模板生成Nginx站点配置,其中引用刚部署的证书路径。
服务重载:使用handler在文件或配置变化后重新加载Nginx,使新证书生效。
2. 变量使用
`ansible_host`:根据inventory中的主机名动态生成证书文件名,方便多主机管理。
私钥路径通常放在`/etc/ssl/private/`,目录权限应为`0750`或`0700`,文件权限`0600`。
3. 模板示例 (nginx_ssl.conf.j2)
nginx
server {
listen 443 ssl;
server_name {{ ansible_host }};
ssl_certificate {{ ssl_cert_path }};
ssl_certificate_key {{ ssl_key_path }};
ssl_trusted_certificate {{ ssl_chain_path }}; # 可选
# 其他SSL配置...
root /var/www/html;
index index.html;
}
4. 安全建议
私钥加密存储:将私钥文件用[Ansible Vault](https://docs.ansible.com/ansible/latest/vault_guide/index.html)加密后放入`files/`,或在Playbook中直接引用加密变量内容。
权限最小化:确保`/etc/ssl/private`目录权限为`0700`,且仅root可访问。
5. 集成Let's Encrypt自动获取证书
如需自动从Let's Encrypt获取证书,可替换复制任务为以下步骤:
yaml
name: 安装certbot
package:
name: certbot
state: present
name: 获取Let's Encrypt证书(使用standalone插件或webroot)
command: >
certbot certonly --standalone
-d {{ ansible_host }}
--non-interactive --agree-tos
--email admin@{{ ansible_host }}
--cert-path {{ ssl_cert_path | dirname }}
args:
creates: "{{ ssl_cert_path }}" # 避免重复执行
notify: reload nginx
之后将证书软链接或复制到目标路径,或直接配置Nginx使用Certbot生成的路径(如`/etc/letsencrypt/live/{{ ansible_host }}/`)。
6. 注意事项
确保目标服务器上已安装Nginx(或其他Web服务器),且服务已启用。
证书文件需要事先准备好,或通过其他方式(如acme.sh)获取。
如果使用私有CA,需将CA证书一并部署。
此Playbook提供了一个可扩展的框架,可根据实际环境调整路径、模块和服务类型。