- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Use Ansible to import Local Certificate
I would like to use an Ansible playbook to import an SSL certificate into my Fortigate appliance and set that newly-imported certificate as the Server Certificate. Does anyone have any code examples on how to do that?
Solved! Go to Solution.
- Labels:
-
FortiGate
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I found that after uploading the certificate to Fortinet, I needed to update the SSL VPN configuration so that the Fortinet appliance was using the latest generated LetsEncrypt certificate. After that, I needed to update the SSO configuration to use the same newly-generated SSL certificate.
Because I wasn't able to find Ansible modules to do that in the `fortinet.fortios collection` collection (someone feel free to correct me if these do exist), I ended up writing a playbook that utilised the Fortinet HTTP API directly.
I will be writing a blog post about this on our website sometime within the next week or two. In the interim, see the entire playbook below:
---
- hosts: all
gather_facts: no
vars:
cert_fc: /path/to/fullchain.pem
cert_pk: /path/to/privkey.pem
cert_fn: /path/to/subdomain.example.com.pem
tasks:
- block:
- name: Create temporary directory
ansible.builtin.tempfile:
state: directory
suffix: ansible_pb
register: temp_dir
- name: Copy Full Chain and Private Key to Temp Folder
ansible.builtin.copy:
src: "{{item}}"
dest: "{{ temp_dir.path }}"
remote_src: yes
loop:
- "{{cert_fc}}"
- "{{cert_pk}}"
- name: Assemble into a cert file
ansible.builtin.assemble:
src: "{{ temp_dir.path }}"
dest: "{{ cert_fn }}"
register: cert
no_log: true
- name: Convert file to PEM to PKCS12
ansible.builtin.command: openssl pkcs12 -export -in {{cert_fc}} -inkey {{cert_pk}} -out {{temp_dir.path}}/domain.pfx -password pass:Example1234
register: cert_pkcs12
when: cert.changed == true
no_log: true
- name: Read certificate into Base64
ansible.builtin.slurp:
src: "{{temp_dir.path}}/domain.pfx"
register: cert_b64
when: cert.changed == true
no_log: true
- name: Upload SSL certificate to Fortinet
ansible.builtin.uri:
url: "https://192.168.1.1/api/v2/monitor/vpn-certificate/local/import?access_token={{ Fortinet_APIKey }}"
method: POST
body_format: json
body:
type: pkcs12
certname: subdomain.example.com
password: Example1234
scope: global
file_content: "{{cert_b64.content}}"
validate_certs: false
when: cert.changed == true
delegate_to: localhost
no_log: true
- name: Change VPN certificate to newly uploaded cert
ansible.builtin.uri:
url: "https://192.168.1.1/api/v2/cmdb/vpn.ssl/settings?access_token={{ Fortinet_APIKey }}"
method: PUT
body:
servercert:
q_origin_key: "subdomain.example.com"
validate_certs: false
body_format: json
when: cert.changed == true
delegate_to: localhost
no_log: true
- name: Change SSO certificate to newly uploaded cert
ansible.builtin.uri:
url: "https://192.168.1.1/api/v2/cmdb/user/saml/fac-sslvpn?access_token={{ Fortinet_APIKey }}"
method: PUT
body:
cert: "subdomain.example.com"
body_format: json
validate_certs: false
when: cert.changed == true
delegate_to: localhost
no_log: true
rescue:
- name: Failed to combine cert
set_stats:
data:
ErrorCode: 166f54e4-d9b7-41b6-9fbc-d56420933f0
- meta: end_play
always:
- name: Remove Temporary Directory
ansible.builtin.file:
path: "{{ temp_dir.path }}"
state: absent
when: temp_dir.path is defined
* Use at your own risk.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello Timothy,
Thank you for using the Community Forum.
I will seek to get you an answer or help. We will reply to this thread with an update as soon as possible.
Regards,
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello Timothy,
We are still looking for someone to help you.
We will come back to you ASAP.
Regards
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello Timothy,
I found this documentation:
Could you please indicate me if it helped?
Regards,
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I found that after uploading the certificate to Fortinet, I needed to update the SSL VPN configuration so that the Fortinet appliance was using the latest generated LetsEncrypt certificate. After that, I needed to update the SSO configuration to use the same newly-generated SSL certificate.
Because I wasn't able to find Ansible modules to do that in the `fortinet.fortios collection` collection (someone feel free to correct me if these do exist), I ended up writing a playbook that utilised the Fortinet HTTP API directly.
I will be writing a blog post about this on our website sometime within the next week or two. In the interim, see the entire playbook below:
---
- hosts: all
gather_facts: no
vars:
cert_fc: /path/to/fullchain.pem
cert_pk: /path/to/privkey.pem
cert_fn: /path/to/subdomain.example.com.pem
tasks:
- block:
- name: Create temporary directory
ansible.builtin.tempfile:
state: directory
suffix: ansible_pb
register: temp_dir
- name: Copy Full Chain and Private Key to Temp Folder
ansible.builtin.copy:
src: "{{item}}"
dest: "{{ temp_dir.path }}"
remote_src: yes
loop:
- "{{cert_fc}}"
- "{{cert_pk}}"
- name: Assemble into a cert file
ansible.builtin.assemble:
src: "{{ temp_dir.path }}"
dest: "{{ cert_fn }}"
register: cert
no_log: true
- name: Convert file to PEM to PKCS12
ansible.builtin.command: openssl pkcs12 -export -in {{cert_fc}} -inkey {{cert_pk}} -out {{temp_dir.path}}/domain.pfx -password pass:Example1234
register: cert_pkcs12
when: cert.changed == true
no_log: true
- name: Read certificate into Base64
ansible.builtin.slurp:
src: "{{temp_dir.path}}/domain.pfx"
register: cert_b64
when: cert.changed == true
no_log: true
- name: Upload SSL certificate to Fortinet
ansible.builtin.uri:
url: "https://192.168.1.1/api/v2/monitor/vpn-certificate/local/import?access_token={{ Fortinet_APIKey }}"
method: POST
body_format: json
body:
type: pkcs12
certname: subdomain.example.com
password: Example1234
scope: global
file_content: "{{cert_b64.content}}"
validate_certs: false
when: cert.changed == true
delegate_to: localhost
no_log: true
- name: Change VPN certificate to newly uploaded cert
ansible.builtin.uri:
url: "https://192.168.1.1/api/v2/cmdb/vpn.ssl/settings?access_token={{ Fortinet_APIKey }}"
method: PUT
body:
servercert:
q_origin_key: "subdomain.example.com"
validate_certs: false
body_format: json
when: cert.changed == true
delegate_to: localhost
no_log: true
- name: Change SSO certificate to newly uploaded cert
ansible.builtin.uri:
url: "https://192.168.1.1/api/v2/cmdb/user/saml/fac-sslvpn?access_token={{ Fortinet_APIKey }}"
method: PUT
body:
cert: "subdomain.example.com"
body_format: json
validate_certs: false
when: cert.changed == true
delegate_to: localhost
no_log: true
rescue:
- name: Failed to combine cert
set_stats:
data:
ErrorCode: 166f54e4-d9b7-41b6-9fbc-d56420933f0
- meta: end_play
always:
- name: Remove Temporary Directory
ansible.builtin.file:
path: "{{ temp_dir.path }}"
state: absent
when: temp_dir.path is defined
* Use at your own risk.