{"id":20263655,"url":"https://github.com/springerpe/ansible-bigiplb-boshrelease","last_synced_at":"2026-04-15T07:39:47.588Z","repository":{"id":80986827,"uuid":"73385314","full_name":"SpringerPE/ansible-bigiplb-boshrelease","owner":"SpringerPE","description":"Add-on for ansible-boshrelease with playbooks and roles to automatically manage F5 BIG-IP LTM","archived":false,"fork":false,"pushed_at":"2017-12-11T16:04:00.000Z","size":44,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-08-02T02:55:32.688Z","etag":null,"topics":["ansible","bosh","bosh-release","f5-lb","f5-pool"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/SpringerPE.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-11-10T13:37:05.000Z","updated_at":"2016-12-02T14:25:46.000Z","dependencies_parsed_at":null,"dependency_job_id":"42515dcb-65f9-40e4-afd1-642866f10540","html_url":"https://github.com/SpringerPE/ansible-bigiplb-boshrelease","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/SpringerPE/ansible-bigiplb-boshrelease","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SpringerPE%2Fansible-bigiplb-boshrelease","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SpringerPE%2Fansible-bigiplb-boshrelease/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SpringerPE%2Fansible-bigiplb-boshrelease/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SpringerPE%2Fansible-bigiplb-boshrelease/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SpringerPE","download_url":"https://codeload.github.com/SpringerPE/ansible-bigiplb-boshrelease/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SpringerPE%2Fansible-bigiplb-boshrelease/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31831849,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-15T07:17:56.427Z","status":"ssl_error","status_checked_at":"2026-04-15T07:17:30.007Z","response_time":63,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ansible","bosh","bosh-release","f5-lb","f5-pool"],"created_at":"2024-11-14T11:35:50.867Z","updated_at":"2026-04-15T07:39:47.567Z","avatar_url":"https://github.com/SpringerPE.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Add-on BOSH Release for [ansible-boshrelease](https://github.com/SpringerPE/ansible-boshrelease)\n\nAdd-on release with ansible playbooks to manage F5 BIG-IP load balancers.\nIt allows you to define/update a F5 virtual server with a pool of backend nodes\nmanaged automatically by BOSH (no need to use static IPs). When you update the \nnumber of instances of the job, the new/old instance will be added/removed \nfrom the pool, and when the node is removed it will keep it available \nwaiting to drain the active connections (with a timeout). \nEverything automatic!, just change the number of instances and run `bosh deploy`! \n\n\n## Usage\n\nThis is and add-on release, it will work only if it is deployed together with the \n*ansible-boshrelease* on the nodes, in particular with **ansible-hook**s job.\nHave a look at [ansible-boshrelease](https://github.com/SpringerPE/ansible-boshrelease)\nfor the requirements and to see how it works.\n\nConsidering v2 manifest style, add the new releases in the `releases` block:\n\n```\nreleases:\n  [...]\n- name: ansible\n  version: latest\n- name: ansible-bigiplb\n  version: latest\n```\n\nthen in your `instance_groups`, add:\n \n```\ninstance_groups:\n  [...]\n  jobs:\n  [...]\n  - name: ansible-hooks\n    release: ansible\n  - name: ansible-bigiplb\n    release: ansible-bigiplb\n```\n\nfinally define the `properties` of the VIP and F5 device:\n\n```\n  properties:\n    ansible_bigiplb:\n      virtual_server_name: \"vs.docker-registry.tools.springer.com.443\"\n      virtual_server_ip: \"10.10.35.230\"\n      virtual_server_port: 443\n      virtual_server_vlans:\n      - \"/Common/VLAN-999\"\n      virtual_server_profiles:\n      - \"/Common/http-default-springer\"\n      - \"/CloudFoundry/docker-registry.tools.springer.com\"\n      irules:\n      - name: \"/CloudFoundry/ir.docker-registry.tools.springer.com\"\n        content: |\n          when HTTP_REQUEST {\n            if {not [HTTP::header exists Docker-Distribution-Api-Version] } {\n              HTTP::header insert \"Docker-Distribution-Api-Version\" \"registry/2.0\"\n            }\n            if {not [HTTP::header exists X-Real-IP] } {\n              HTTP::header insert \"X-Real-IP\" [IP::remote_addr]\n            }\n            if {not [HTTP::header exists X-Forwarded-Proto] } {\n              HTTP::header insert \"X-Forwarded-Proto\" \"https\"\n            }\n            if {not [HTTP::header exists X-Forwarded-For] } {\n              HTTP::header insert \"X-Forwarded-For\" [IP::remote_addr]\n            }\n          }\n      pool_name: \"pl.docker-registry.tools.springer.com.5000\"\n      pool_members_port: 5000\n      server:\n      - device: \"f5-device\"\n        ip: \"127.0.0.1\"\n        user: \"user\"\n        password: \"password\"\n        partition: \"CloudFoundry\"\n  [...]\n```\n\nand that's all!, run `bosh-deploy` and see how everything is done in the\nF5: vip and pool created and nodes added to the pool. Moreover, when the \nnumber of the instances of the job changes, they will be added or \nremoved from the F5 pool. \n\nNote that irules will be deleted only if they have a content, in the\nsame way they were created: an irule without content means just a \nreference (it will not be created/deleted), but if it includes a\ncontent, it is assumed that it has to be managed here.\n\nDeleting a deployment requires a special consideration, if you do it\ndirectly, the F5 will keep the VIP and pool configuration (empty). In order\nto remove also those settings and maintain everything clean, before deleting \nthe deployment, you have to define an errand job:\n\n```\n- name: f5-clean\n  lifecycle: errand\n  instances: 1\n  vm_type: medium\n  stemcell: trusty\n  vm_extensions: []\n  azs:\n  - Online_Prod\n  networks:\n  - name: online\n  jobs:\n  - name: ansible-distclean\n    release: ansible\n  - name: ansible-bigiplb\n    release: ansible-bigiplb\n  properties:\n    ansible_bigiplb:\n      virtual_server_name: \"vs.docker-registry.tools.springer.com.443\"\n      virtual_server_ip: \"10.10.35.230\"\n      virtual_server_port: 443\n      irules:\n      - name: \"/CloudFoundry/ir.docker-registry.tools.springer.com\"\n        content: true\n      pool_name: \"pl.docker-registry.tools.springer.com.5000\"\n      pool_members_port: 5000\n      server:\n      - device: \"f5-device\"\n        ip: \"127.0.0.1\"\n        user: \"user\"\n        password: \"password\"\n        partition: \"CloudFoundry\"\n\n```\n\nthen run: `bosh run errand f5-clean` to delete all F5 settings. After that\nyou can run `bosh delete deployment \u003cname\u003e`.\n\n\n# Mysql-Galera cluster example\n\nThis is an example about how to define a MySQL Galera cluster using the\n[cf-myslq-release](https://github.com/cloudfoundry/cf-mysql-release) bosh release.\nHere the proxies are not used, so it is a deployment of 2 mysql nodes and one arbitrator.\nThe reason not to use a proxy is just to simplify the infrastructure, and all they\nfunctionality has been defined in the F5. Also, optionally, it helps to make the routing\npersistent to the same backend from the same client by using an irule. You do not need\nthe irule if you know the clients are able to handle (or do not cause) deadlocks\nand rollbacks.\n\n```\n  jobs:\n  - release: cf-mysql\n    name: mysql\n  - name: smoke-tests-user\n    release: cf-mysql\n  - name: ansible-hooks\n    release: ansible\n  - name: ansible-bigiplb\n    release: ansible-bigiplb\n    properties:\n      ansible_bigiplb:\n        virtual_server_name: \"vs.exp-mysql-galera.dc.springernature.pe.3306\"\n        virtual_server_ip: \"2.2.2.2\"\n        virtual_server_port: 3306\n        virtual_server_profiles:\n        - \"/Common/tcp\"\n        irules:\n        - name: \"/CloudFoundry/ir00_persistence.exp-mysql-galera.dc.springernature.pe\"\n          content: \"when CLIENT_ACCEPTED { persist uie \\\"[IP::client_addr]\\\" }\"\n        pool_name: \"pl.exp-mysql-galera.dc.springernature.pe.3306\"\n        pool_members_port: 3306\n        pool_monitors:\n       - name: \"/Cloudfoundry/hm.exp-mysql-galera.dc.springernature.pe.9200\"\n         port: 9200\n         type: \"http\"\n         parent: \"http\"\n         parent_partition: \"Common\"\n         timeout: 4\n         interval: 5\n         time_until_up: 30\n         send: \"GET /api/v1/status HTTP/1.1\\r\\nUser-Agent: F5-healthcheck\\r\\nConnection: Close\\r\\n\\r\\n\"\n         receive: \"^HTTP/1\\.1 200 OK\"\n        server:\n        - device: \"XXXXXXXXXXXX\"\n          ip: \"1.1.1.1\"\n          user: \"user\"\n          password: \"pass\"\n          partition: \"CloudFoundry\"\n```\n\n\n## Additional features\n\nThere is another way to use this release: as an errand job. Useful if you do not\nwant to include ansible in all the instances of your deployment, or you want to \nautomate a F5 LB pool with bosh for other jobs, just create an errand job in your\nmanifest including the `ansible-deploy` job:\n\n```\n- name: f5-setup\n  lifecycle: errand\n  instances: 1\n  vm_type: medium\n  stemcell: trusty\n  vm_extensions: []\n  azs:\n  - Online_Prod\n  networks:\n  - name: online\n  jobs:\n  - name: ansible-deploy\n    release: ansible\n  - name: ansible-bigiplb\n    release: ansible-bigiplb\n  properties:\n    ansible_bigiplb:\n      virtual_server_name: \"vs.docker-registry.tools.springer.com.443\"\n      virtual_server_ip: \"10.10.35.230\"\n      virtual_server_port: 443\n      virtual_server_vlans:\n      - \"/Common/VLAN-999\"\n      virtual_server_profiles:\n      - \"/Common/http-default-springer\"\n      - \"/CloudFoundry/docker-registry.tools.springer.com\"\n      irules:\n      - name: \"/CloudFoundry/ir.docker-registry.tools.springer.com\"\n        content: |\n          when HTTP_REQUEST {\n            if {not [HTTP::header exists Docker-Distribution-Api-Version] } {\n\t      HTTP::header insert \"Docker-Distribution-Api-Version\" \"registry/2.0\"\n            }\n            if {not [HTTP::header exists X-Real-IP] } {\n              HTTP::header insert \"X-Real-IP\" [IP::remote_addr]\n            }\n            if {not [HTTP::header exists X-Forwarded-Proto] } {\n              HTTP::header insert \"X-Forwarded-Proto\" \"https\"\n            }\n            if {not [HTTP::header exists X-Forwarded-For] } {\n              HTTP::header insert \"X-Forwarded-For\" [IP::remote_addr]\n            }\n          }\n      pool_name: \"pl.docker-registry.tools.springer.com.5000\"\n      pool_members_port: 5000\n      server:\n      - device: \"f5-device\"\n        ip: \"127.0.0.1\"\n        user: \"user\"\n        password: \"password\"\n        partition: \"CloudFoundry\"\n```\n\nand run `bosh run errand f5-setup` \n\n\n# Known issues\n\nThe automatic instance management is done on each node by taking the default IP \naddress of itself, so if a node has multiple IP addresses the one with the \ndefault GW will be taken.\n\nIf a node suddenly crashes, it won't trigger the drain actions and its IP will\nremain in the F5 LB as inactive. If Bosh resurrector is enabled, it could happen\nthat a new instance gets a different IP (than the crashed node) and no process\nwill remove the old IP from the F5 pool, in case of this situation, the way\n-for now- is manually delete the inactive node from the pool. The errand job\nto clean the F5 resources is not affected by this situation because it always\ngets the facts (nodes) from the F5.\n\n\n# Design\n\nAll variables used in this release are are defined in the ansible inventory file,\nso the playbooks are re-usable outside this release (useful for testing) by \nre-defining a inventory with the variables needed by the playbooks.\n\nAll actions/playbooks (thanks to ansible) are idempotent.\n\n\n# Creating a new final release\n\nRun: `./bosh_final_release`\n\n\n# Author\n\nSpringerNature Platform Engineering, José Riguera López (jose.riguera@springer.com)\n\nCopyright 2017 Springer Nature\n\n\n\n# License\n\nApache 2.0 License\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspringerpe%2Fansible-bigiplb-boshrelease","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fspringerpe%2Fansible-bigiplb-boshrelease","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspringerpe%2Fansible-bigiplb-boshrelease/lists"}