Exercise 3.3 - Deploying a WAF policy through AS3¶
Objective¶
Demonstrate building an Application Service through an AS3 declaration where a WAF policy gets added.
Guide¶
Make sure the BIG-IP configuration is clean, run exercise 3.2-as3-delete before proceeding
Step 1
In exercise 3.0-as3-intro it is explained how AS3 works.
Throughout this exercise we will use three files. Create the two files below
waf_tenant_base.j2
{
"class": "AS3",
"action": "deploy",
"persist": true,
"declaration": {
"class": "ADC",
"schemaVersion": "3.2.0",
"id": "testid",
"label": "test-label",
"remark": "test-remark",
"WorkshopExample":{
"class": "Tenant",
{{ as3_app_body }}
}
}
}
waf_tenat_base.j2
- is an F5 provided standard template and will include the pointer towards thesecond jinja2 template which includes the actual AS3 schema.
waf_as3_template.j2
"web_app": {
"class": "Application",
"template": "http",
"serviceMain": {
"class": "Service_HTTP",
"virtualAddresses": [
"{{private_ip}}"
],
"pool": "app_pool",
"policyWAF": {
"use": "new_asm_policy"
}
},
"app_pool": {
"class": "Pool",
"monitors": [
"http"
],
"members": [
{
"servicePort": 80,
"serverAddresses": [
{% set comma = joiner(",") %}
{% for mem in pool_members %}
{{comma()}} "{{ hostvars[mem]['ansible_host'] }}"
{% endfor %}
]
}
]
},
"new_asm_policy": {
"class": "WAF_Policy",
"url": "https://raw.githubusercontent.com/f5devcentral/FAS-ansible-workshop-101/master/3.3-as3-asm/Test_WAF_Policy.xml",
"ignoreChanges": true
}
}
Most of the template is already explained in exercise 3.0-as3-intro. Compared to the original a WAF policy has been added to the
url
defines the URL where to pull the ASM policy from.
WRITE THESE TEMPLATES TO YOUR WORKING DIRECTORY
Step 3
Using your text editor of choice create a new file called waf-as3.yml
:
Step 4
Enter the following play definition into waf-as3.yml
:
- name: Deploy WAF profile using AS3
hosts: lb
connection: local
gather_facts: false
vars:
pool_members: "{{ groups['webservers'] }}"
Step 5
Append the following to the waf-as3.yml Playbook.
tasks:
- set_fact:
provider:
server: "{{private_ip}}"
user: "{{ansible_user}}"
password: "{{ansible_ssh_pass}}"
server_port: 8443
validate_certs: no
- name: Provision BIG-IP with ASM module
bigip_provision:
provider: "{{provider}}"
module: "asm"
level: "nominal"
The provider gets set and the ASM module gets provisioned to level ‘nominal’.
Step 6
Append the following to the waf-as3.yml playbook.
- name: CREATE AS3 JSON BODY
set_fact:
as3_app_body: "{{ lookup('template', 'waf_as3_template.j2', split_lines=False) }}"
as3_app_body
will get defined via set_fact
and renders the waf_as3_template.j2 that is provided.
Step 6
Append the following to the waf-as3.yml Playbook.
- name: PUSH AS3
uri:
url: "https://{{ ansible_host }}:8443/mgmt/shared/appsvcs/declare"
method: POST
body: "{{ lookup('template','waf_tenant_base.j2', split_lines=False) }}"
status_code: 200
timeout: 300
body_format: json
force_basic_auth: yes
user: "{{ ansible_user }}"
password: "{{ ansible_ssh_pass }}"
validate_certs: no
delegate_to: localhost
Pushing AS3 has been explained in exercise 3.0-as3-intro. Basically the
uri
parameter gets used to create the REST body. The declaration uses ‘waf_tenant_base.j2’ as the body.
Step 7
Run the playbook - exit back into the command line of the control host and execute the following:
[student1@ansible ~]$ ansible-playbook waf-as3.yml
Playbook Output¶
The output will look as follows.
PLAY [Deploy WAF profile using AS3] ********************************************************************************************************************
TASK [set_fact] ****************************************************************************************************************************************
ok: [f5]
TASK [Provision BIG-IP with ASM module] ****************************************************************************************************************
changed: [f5]
TASK [CREATE AS3 JSON BODY] ****************************************************************************************************************************
ok: [f5]
TASK [PUSH AS3] ****************************************************************************************************************************************
ok: [f5 -> localhost]
PLAY RECAP *********************************************************************************************************************************************
f5 : ok=4 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Verifying the Solution¶
Login to the F5 with your web browser to see what was configured. Grab the IP information for the F5 load balancer from the lab_inventory/hosts file, and type it in like so: https://X.X.X.X:8443/
- Click on the Local Traffic on the lefthand menu
- Click on Virtual Servers.
- On the top right, click on the drop down menu titled
Partition
and select WorkshopExample - The Virtual Server
serviceMain
will be displayed. - Click on
serviceMain
and select the tab Security and click Policies. The Application Security policy isenabled
and the usedpolicy: new_asm_policy
You have finished this exercise, section 3 and made it tyo the end of FAS-ansible-workshop-101!.