This fabric workshop aims to create a deploy tool using Fabric that can deploy code to servers defined in roles, show existing tags, change to a different tagged version, and remove tags. The agenda includes demonstrating local tasks, remote tasks using an Ansible inventory file, and functions for mkdir, cd, and uploading files. Fabric provides a simple way to automate operations across multiple servers.
9. GOAL
Create deploy tool
- deploy
- dev/staging/production
- tag name (any ascii)
- rollback
- use any tag deployed
- tag list
- remove tag.
10. GOAL
$ fab help
Usage:
<Deploy>
$ fab -R [ROLE] deploy
$ fab -R [ROLE] deploy:mode=[MODE],tag=[TAG],force=[True]
deploy source to servers which are defined as ROLE
Options:
mode : 'production', 'staging', ‘development(default)'
tag : any ASCII tag. (default = Epoch time + microtime)
force: set 'True' to overwrite. (default = False)
<Show existed tags>
$ fab -R [ROLE] tags
show existed tags
<Change version>
$ fab -R [ROLE] change:tag=XXXXXX
change working version to another tagged source
tag should be exactly same as shown by Tags command
<Remove specified tag>
$ fab -R [ROLE] remove:tag=XXXXXX
remove exist tags
tag should be exactly same as shown by Tags command
19. Remote task (2)
$ fab remotetest
No hosts found. Please specify (single) host string for connection: {IP_ADDRESS}
[192.168.33.50] run: ls -al
[192.168.33.50] out: total 44
[192.168.33.50] out: drwx------. 6 vagrant vagrant 4096 Jan 14 05:58 .
:
[192.168.33.50] out: drwxrwxr-x 3 vagrant vagrant 4096 Jan 13 11:47 src
[192.168.33.50] out:
total 44
$ fab remotetest
target host required...
$ fab -H {IP_ADDRESS} remotetest
20. Remote task (trouble?)
~/.ssh/config
---
Host {IP_ADDRESS_OF_YOUR_VAGRANT_MACHINE}
User vagrant
TCPKeepAlive yes
IdentityFile {PRIVATE_KEY_OF_YOUR_VAGRANT_MACHINE}
IdentitiesOnly yes
ControlPersist 2h
Where is the private key??
$ vagrant ssh-config
api.env.use_ssh_config = True
set option in your fabfile.py
21. Using ROLE instead of -H
$ fab -R httpd-server remotetest
:
from fabric.api import env
from fabric.decorators import roles
env.user = user
env.roledefs.update({
‘httpd-server': [‘{IP_ADDRESS}’, ‘{IP_ADDRESS}’],
'toolservers': [‘{IP_ADDRESS}’],
})
@roles(‘httpd-server')
def YOUR_COMMAND:
pass
22. Using ROLE (2)
But...
We want to use
Ansible inventory (hosts) file.
* Target host definition should be only one.
* The definition of targets in Fabric is in code,
so we should use Ansible’s inventory file.
23. Using Ansible inventory
fabfile.py
---
from ansible import inventory
from fabric.api import env, run, local
from fabric import api
inventory = inventory.Inventory('./hosts')
env.roledefs = inventory.groups_list()
env.use_ssh_config = True
def remotetest():
run('ls -al')
hosts
---
[httpd-server]
192.168.33.50
see) Ansible(1-3)
27. mkdir and cd
fabfile.py
---
from ansible import inventory
from fabric.api import env, run, local, cd
from fabric import api
inventory = inventory.Inventory('./hosts')
env.roledefs = inventory.groups_list()
env.use_ssh_config = True
def mkdir_and_cd():
run(‘mkdir -p TMP’)
with cd(‘TMP’):
run(‘pwd’)
$ fab -R httpd-server mkdir_and_cd
28. mkdir and cd (2)
fabfile.py
---
:
from fabric.contrib import files
:
:
def mkdir_and_cd():
if not files.exists(‘TMP’):
run(‘mkdir -p TMP’)
with cd(‘TMP’):
run(‘ls -al’)
$ fab -R httpd-server mkdir_and_cd
29. mkdir, cd and put
fabfile.py
---
:
from fabric.api import env, run, local, cd, put
from fabric.contrib import files
:
:
def mkdir_cd_and_put():
if not files.exists(‘TMP’):
run(‘mkdir -p TMP’)
with cd(‘TMP’):
if not files.exists({DEST_FILE}):
put({SRC_FILE}, {DEST_FILE})
$ fab -R httpd-server mkdir_cd_and_put