[PYTHON] Why we chose Fabric as our deployment tool

All the following entries are sold. I thought I'd change it to a better one because I'll put it together myself, but the original entry was too good and the entry was almost the same.

Deployment automation for teams with multiple projects

Why I chose Fabric

Originally it was automated with a shell script. It wasn't a big problem, but I felt like someone who was good at shell scripts would maintain it, so I wanted to make it easier for anyone to fix it. The question of which one to use, Capistrano, is that the company I'm currently in is Python-based, and few people touch Ruby, so I chose Fabric as the elimination method.

strategy

As mentioned in the original entry, the troublesome thing about Fabric is that it doesn't have a base framework, so you have to write it from scratch. We decided to create a minimal framework and provide it to the team.

├── README.md
├── lib
│   ├── git.py
│   └── hipchat.py
├── projectA
│   ├── README.md
│   ├── config
│   │   ├── common.py
│   │   ├── develop.py
│   │   ├── production.py
│   │   └── staging.py
│   └── fabfile.py
├── projectB
├── projectC

Create a directory for each project, and manage those that can be shared in the lib directory. The difference from the original entry is that the common directory has been renamed to lib, and the config directory absorbs different settings for each environment. (I think I'll go back to common.)

Unification of terms

The interface is unified even if the projects are different in order to eliminate personality.

Normal deployment

fab -H host1,host2 develop deploy

Deploy with specified branch

fab -H host1,host2 develop deploy:feat/ABC

roll back

fab -H host1,host2 develop rollback

Environment-dependent files

Since the standard Fabric load_settings () can only handle strings, I made it possible to use dictionaries and lists as follows. The amount of code has increased a little, but the extensibility has increased.

fabfile.py

@task
def develop(user='vagrant'):
    """Development environment"""
    config.develop.develop(user)

@task
def staging(user=''):
    """Staging environment"""
    config.staging.staging(user)

@task
def production(user=''):
    """Production environment"""
    config.production.production(user)

@task
def deploy():
    """Deploy"""
Write the process here

config/develop.py

def develop(user='vagrant'):
    """Development environment"""
    env.environment = 'develop'
    env.user = user
    …
    …

Kindness

Deploy on the assumption that it will fail --hitode909's diary

I'm really sorry for the plagiarism, but I'd like to do this. I want to reduce the number of operations for viewing the manual as much as possible.

Don't panic

I'll teach you the rollback command

Tip: To get it back, run the following command
fab -H host1,host2 production rollback

Don't get lost

Do not output unnecessary things

I want the deployer to know what to do next by looking at the log on the screen. Even those who deploy for the first time should not hesitate.

fab -l

Fabric standard command. Write comments properly and let users use it with confidence.

% fab -l
Available commands:

deploy deploy
develop development environment
production production environment
rollback rollback
staging staging environment

Write an easy-to-understand README.md

It's okay to write in Confluence, but if it's something that GIT manages, I'd like to write it in a README and put a link to Confluence.

Write an easy-to-understand README.md

Name
====

Overview

## Description

## Demo

## VS. 

## Requirement

## Usage

## Install

## Contribution

## Licence

[MIT](https://github.com/tcnksm/tool/blob/master/LICENCE)

## Author

[tcnksm](https://github.com/tcnksm)

For in-house projects, also write:

## Document

## Ticket

## Deploy

## Test

By writing these, the members who participated in the project for the first time will not get lost. All you have to do is complete the repository, but historic projects may have documentation scattered around. There is no problem if the members have been involved in the project for a long time, but it will be a burden for newly joined members. I want to make sure that any member can participate in the project smoothly.

Summary

I also wanted to use Consul and Capistrano, but when I tried to solve the current problem smoothly, it became like this. I'm looking forward to seeing how this mechanism survives a year later.

regret

I could write a test, but I couldn't take that much time. The following is a reference link.

https://github.com/fabric/fabric/tree/master/tests http://www.obeythetestinggoat.com/unit-testing-fabric-deployment-scripts.html

There are also the following libraries as standard in Fabric.

class FabricTest(object):
    """
    Nose-oriented test runner which wipes state.env and provides file helpers.
    """

reference

Recommended Posts

Why we chose Fabric as our deployment tool
Idempotent guarantee with deployment tool fabric + cuisine