Skip to content

2 Configuration

Colin Stubbs edited this page Jun 11, 2020 · 2 revisions

Dehydrated BIG-IP Ansible Configuration

Mandatory

Ansible Inventory

At minimum two configuration files need to be modified to configure things.

  1. An Ansible inventory file describing BIG-IP systems and how to connect to them, optionally encrypted using Ansible Vault
  2. A dehydrated conf.d file, e.g. the default conf.d/local.sh file, which should contain environment variables used by the hook scripts

A basic inventory file for a single BIG-IP will look like the following.

[bigip]
192.168.1.245

[bigip:vars]
bigip_username=admin
bigip_password=Exampl3#
bigip_shell_username=root
bigip_shell_password=Exampl3#

If a second BIG-IP as part of a HA pair was present, it might look like this.

[bigip]
192.168.1.245
192.168.1.246

[bigip:vars]
bigip_username=admin
bigip_password=Exampl3#
bigip_shell_username=root
bigip_shell_password=Exampl3#
[user@host ~]$ echo -n 'BigLongRandoSecret' > ~/.ansible/vault.pass

[user@host ~]$ ansible-vault encrypt /etc/dehydrated/ansible/bigip-inventory.ini 
New Vault password: 
Confirm New Vault password: 
Encryption successful
[user@host ~]$

[user@host ~]$ ansible-vault encrypt /etc/dehydrated/ansible/bigip-inventory.ini 
New Vault password: 
Confirm New Vault password: 
Encryption successful
[user@host ~]$ cat /etc/dehydrated/ansible/bigip-inventory.ini
$ANSIBLE_VAULT;1.1;AES256
31326235623932396632666537643561343330656331383932323861663964383732396664363237
6363303133323262613830646537363830376666616465300a666538636633636363323635346562
65356431633331643164663032313637666634663038636132613638663635396163396632346536
6631353739386339310a316231363632616339363934393331663838643037363462633639326561
39356165316266613461653039656239666262343939656366306336663264323536653332666663
65366330383135613838306366643032343239626230393165306563363364656632663330646461
63373730326335363531326364643566353237396166633238326131333666643036343235323939
33316662656139393664376564613761613234376333313737653061333737646665386364303635
34346265313933356564306435643763343232643263316135613436653335333864393832383434
38643262353337643638636363386537353961306662306561373232336365356536333462333664
363764333566653632333932383530643362
[user@host ~]$

dehydrated Ansible configuration variables

NOTE: This wiki will assume you put these variables in /etc/dehydrated/conf.d/ansible.sh

ANSIBLE_ARGS=${ANSIBLE_ARGS:-""}
ANSIBLE_INVENTORY=${ANSIBLE_INVENTORY:-"/etc/dehydrated/ansible/bigip-inventory.ini"}
ANSIBLE_PLAYBOOK_CLEAN_CHALLENGE=${ANSIBLE_PLAYBOOK_CLEAN_CHALLENGE:-"/etc/dehydrated/ansible/playbooks/bigip-clean_challenge.yml"}
ANSIBLE_PLAYBOOK_DEPLOY_CERT_MANAGEMENT=${ANSIBLE_PLAYBOOK_DEPLOY_CERT_MANAGEMENT:-"/etc/dehydrated/ansible/playbooks/bigip-deploy_cert-management.yml"}
ANSIBLE_PLAYBOOK_DEPLOY_CERT_TRAFFIC=${ANSIBLE_PLAYBOOK_DEPLOY_CERT_TRAFFIC:-"/etc/dehydrated/ansible/playbooks/bigip-deploy_cert-traffic.yml"}
ANSIBLE_PLAYBOOK_DEPLOY_CHALLENGE=${ANSIBLE_PLAYBOOK_DEPLOY_CHALLENGE:-"/etc/dehydrated/ansible/playbooks/bigip-deploy_challenge.yml"}

dehydrated F5 BIG-IP configuration variables

NOTE: This wiki will assume you put these variables in /etc/dehydrated/conf.d/bigip.sh

BIGIP_CLIENT_SSL_MANAGE=${BIGIP_CLIENT_SSL_MANAGE:-1}
BIGIP_CLIENT_SSL_PARENT=${BIGIP_CLIENT_SSL_PARENT:-"/Common/clientssl"}
BIGIP_DATA_GROUP_NAME=${BIGIP_DATA_GROUP_NAME:-"ACME_http-01"}
BIGIP_ISSUER_CERT=${BIGIP_ISSUER_CERT:-"Lets-Encrypt-X3"}
BIGIP_PARTITION=${BIGIP_PARTITION:-"Common"}
BIGIP_SAVE_CONFIG=${BIGIP_SAVE_CONFIG:-1}
BIGIP_SYNC_CONFIG=${BIGIP_SYNC_CONFIG:-0}
BIGIP_SYNC_DEVICE_GROUP=${BIGIP_SYNC_DEVICE_GROUP:-"SYNC-FAILOVER-1"}

Optional

lexicon configuration

Some environment variables are essential, you should add the following to a .sh file in /etc/dehydrated/conf.d at minimum.

NOTE: This wiki will assume you put these variables in /etc/dehydrated/conf.d/lexicon.sh

LEXICON_ARGS=${LEXICON_ARGS:-""}
LEXICON_PROVIDER=${LEXICON_PROVIDER:-"cloudflare"}
LEXICON_PROVIDER_ARGS=${LEXICON_PROVIDER_ARGS:-""}

BLAH

LEXICON_CLOUDFLARE_TOKEN=${LEXICON_CLOUDFLARE_TOKEN:-"AUTH_TOKEN_GOES_HERE"}

While you can separate the config into /etc/lexicon/lexicon_%{PROVIDER}%.yml files, it seems cleaner/simpler to consolidate to a single /etc/lexicon/lexicon.yml file.

To use this, you need to pass the --config-dir option to lexicon when it runs. To make dehydrated do this set the following in /etc/dehydrated/conf.d/local.sh

LEXICON_ARGS=${LEXICON_ARGS:-"--config-dir /etc/lexicon"}

NOTE: This seems to require the very latest version of lexicon. If you're using a version less than 3.3.24 results may vary.

The below example shows minimal configurations for both Azure DNS and CloudFlare.

[user@host ~]$ cat /etc/lexicon/lexicon.yml 
azure:
  auth_client_id: AZURE_APP_CLIENT_ID
  auth_client_secret: AZURE_APP_CLIENT_SECRET
  auth_subscription_id: AZURE_SUBSCRIPTION_ID
  auth_tenant_id: AZURE_TENANT_ID
  resource_group: AZURE_RESOURCE_GROUP_NAME
cloudflare:
  auth_token: CLOUDFLARE_AUTH_TOKEN
[user@host ~]$

Test lexicon out directly to ensure it's working as intended.

Example against CloudFlare,

[user@host ~]$ dig @1.1.1.1 TXT test.routedlogic.net

; <<>> DiG 9.11.13-RedHat-9.11.13-5.el8_2 <<>> @1.1.1.1 TXT test.routedlogic.net
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 19344
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;test.routedlogic.net.		IN	TXT

;; AUTHORITY SECTION:
routedlogic.net.	300	IN	SOA	dana.ns.cloudflare.com. dns.cloudflare.com. 2034314889 10000 2400 604800 3600

;; Query time: 33 msec
;; SERVER: 1.1.1.1#53(1.1.1.1)
;; WHEN: Fri Jun 12 06:49:18 AEST 2020
;; MSG SIZE  rcvd: 111

[user@host ~]$ 

[user@host ~]$ lexicon --config-dir /etc/lexicon cloudflare --name test.routedlogic.net --content "1234" create routedlogic.net TXT
RESULT
------
True
[user@host ~]$

[user@host ~]$ dig @1.1.1.1 TXT test.routedlogic.net

; <<>> DiG 9.11.13-RedHat-9.11.13-5.el8_2 <<>> @1.1.1.1 TXT test.routedlogic.net
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 63568
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 5

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;test.routedlogic.net.		IN	TXT

;; ANSWER SECTION:
test.routedlogic.net.	3487	IN	TXT	"1234"

;; AUTHORITY SECTION:
routedlogic.net.	169425	IN	NS	dana.ns.cloudflare.com.
routedlogic.net.	169425	IN	NS	will.ns.cloudflare.com.

;; ADDITIONAL SECTION:
will.ns.cloudflare.com.	71108	IN	A	173.245.59.149
will.ns.cloudflare.com.	71108	IN	AAAA	2606:4700:58::adf5:3b95
dana.ns.cloudflare.com.	58998	IN	A	173.245.58.105
dana.ns.cloudflare.com.	99034	IN	AAAA	2606:4700:50::adf5:3a69

;; Query time: 33 msec
;; SERVER: 1.1.1.1#53(1.1.1.1)
;; WHEN: Fri Jun 12 07:04:55 AEST 2020
;; MSG SIZE  rcvd: 209

[user@host ~]$

[user@host ~]$ lexicon --config-dir /etc/lexicon cloudflare --name test.routedlogic.net delete routedlogic.net TXT
RESULT
------
True
[user@host ~]$