Skip to content

Commit

Permalink
Ansible (#18)
Browse files Browse the repository at this point in the history
* initial ansible commit

* add CLI command for starting and stopping in the background

* start draft sidecar upon new deployment

* add deploy command for ansible

* update documentation with ansible deployment

* fix two small type check errors. likely due to new version of pyre

* add dependency for types-psutil
  • Loading branch information
eriktaubeneck authored May 13, 2024
1 parent eb3db84 commit c3cc92d
Show file tree
Hide file tree
Showing 12 changed files with 338 additions and 30 deletions.
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,17 @@ __pycache__*
tmp/
IGNORE-ME*
.pyre/*
.draft

# local env files
.env*

# local certs
local_dev/config/cert.pem
local_dev/config/key.pem

# generated config directory
config/

# installed traefik binary
traefik
33 changes: 13 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,21 +183,19 @@ The public content will also need to be pasted into `local_dev/config/network.to

*Instructions for AWS Linux 2023*

1. **Python3.11**: Install with `sudo yum install python3.11`
2. **git**: Install with `sudo yum install git`
3. **draft** (this package):
1. Clone with `git clone https://github.com/private-attribution/draft.git`
2. Enter directory `cd draft`.
3. Create virtualenv: `python3.11 -m venv .venv`
4. Use virtualeenv: `source .venv/bin/activate`
5. Upgrade pip: `pip install --upgrade pip`
6. Install: `pip install --editable .`
4. **traefik**:
1. Download version 2.11: `wget https://github.com/traefik/traefik/releases/download/v2.11.0/traefik_v2.11.0_linux_amd64.tar.gz`
2. Validate checksum: `sha256sum traefik_v2.11.0_linux_amd64.tar.gz` should print `7f31f1cc566bd094f038579fc36e354fd545cf899523eb507c3cfcbbdb8b9552 traefik_v2.11.0_linux_amd64.tar.gz`
3. Extract the binary: `tar -zxvf traefik_v2.11.0_linux_amd64.tar.gz`
5. **tmux**: `sudo yum install tmux`
1. Provision an EC2 instance. Download the provided `ssh_connect.pem` key and add it to `~/.ssh`.
2. Point a subdomain of a domain you control to the public IP address.
3. Add the host to your `~/.ssh/config` file:
```
Host ipa
Hostname <subdomain-name-for-helper>
User ec2-user
IdentityFile ~/.ssh/ssh_connect.pem
```
4. Update the `draft/ansible/inventory.ini` file to only include a single host. (Unless you are running all 4 servers.)
5. Provision your machine: `ansible-playbook -i ansible/inventory.ini ansible/provision.yaml`

To deploy new changes in draft, run: `ansible-playbook -i ansible/inventory.ini ansible/deploy.yaml`

### Generating TLS certs with Let's Encrypt

Expand Down Expand Up @@ -237,16 +235,11 @@ One you know these:

### Run draft

You'll want this to continue to run, even if you disconnect from the host, so it's a good idea to start a tmux session:

```
tmux new -s draft-session
```

```
draft start-helper-sidecar --identity <identity> --root_domain example.com --config_path config
```

This will start the sidecar in the background. To confirm, visit `example.com/status`.



Expand Down
16 changes: 16 additions & 0 deletions ansible/deploy.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
- name: Deploy updates to Draft
hosts: all
tasks:
# - name: Stop helper sidecar
# command: '{{ ansible_env.HOME }}/draft/.venv/bin/draft stop-helper-sidecar'
- name: Pull new commits from GitHub
git:
repo: 'https://github.com/private-attribution/draft.git'
dest: '{{ ansible_env.HOME }}/draft'
update: yes
- name: Checkout and pull main branch
command: git pull origin main
args:
chdir: '{{ ansible_env.HOME }}/draft'
# - name: Start helper sidecar
# command: '{{ ansible_env.HOME }}/draft/.venv/bin/draft start-helper-sidecar'
7 changes: 7 additions & 0 deletions ansible/inventory.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[myhosts]
ipa-dev
ipa-1
ipa-2
ipa-3
[myhosts:vars]
ansible_python_interpreter=/usr/bin/python3
92 changes: 92 additions & 0 deletions ansible/provision.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
- name: Setup IPA Helper
hosts: all
tasks:
- name: Print HOME directory
debug:
var: ansible_env.HOME

- name: Check if Python3.11 is installed
command: python3.11 --version
register: python_installed
failed_when: false
changed_when: false

- name: Install Python3.11
yum:
name: python3.11
state: latest
become: yes
when: python_installed.rc != 0

- name: Check if Git is installed
command: git --version
register: git_installed
failed_when: false
changed_when: false

- name: Install Git
yum:
name: git
state: latest
become: yes
when: git_installed.rc != 0

- name: Install pip3
command: python3.11 -m ensurepip
become: yes
- name: Upgrade pip3
command: python3.11 -m pip install --upgrade pip
become: yes

- name: Clone repository if it doesn't exist
git:
repo: 'https://github.com/private-attribution/draft.git'
dest: '{{ ansible_env.HOME }}/draft'
update: no

- name: Create virtualenv if it doesn't exist
command: python3.11 -m venv .venv
args:
chdir: '{{ ansible_env.HOME }}/draft'
creates: '{{ ansible_env.HOME }}/draft/.venv'

- name: Install package in editable mode
pip:
name: '{{ ansible_env.HOME }}/draft'
editable: yes
virtualenv: '{{ ansible_env.HOME }}/draft/.venv'
virtualenv_python: python3.11

- name: Check if Traefik is installed
command: '{{ ansible_env.HOME }}/draft/traefik version'
register: traefik_installed
failed_when: false
changed_when: false

- name: Download Traefik
get_url:
url: 'https://github.com/traefik/traefik/releases/download/v2.11.0/traefik_v2.11.0_linux_amd64.tar.gz'
dest: '{{ ansible_env.HOME }}/traefik_v2.11.0_linux_amd64.tar.gz'
checksum: 'sha256:7f31f1cc566bd094f038579fc36e354fd545cf899523eb507c3cfcbbdb8b9552'
when: traefik_installed.rc != 0

- name: Ensure extraction directory exists
file:
path: '{{ ansible_env.HOME }}/traefix_extract/'
state: directory

- name: Extract Traefik
unarchive:
src: '{{ ansible_env.HOME }}/traefik_v2.11.0_linux_amd64.tar.gz'
dest: '{{ ansible_env.HOME }}/traefix_extract/'
remote_src: yes
when: traefik_installed.rc != 0

- name: Copy Traefik binary into draft directory
copy:
src: '{{ ansible_env.HOME }}/traefix_extract/traefik'
dest: '{{ ansible_env.HOME }}/draft'
remote_src: yes

- name: Run draft start-helper-sidecar
command: '{{ ansible_env.HOME }}/draft/.venv/bin/draft start-helper-sidecar'
11 changes: 11 additions & 0 deletions etc/start_helper_sidecar.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/bin/bash

config_path=$1
root_path=$2
root_domain=$3
sidecar_domain=$4
helper_port=$5
sidecar_port=$6
identity=$7

nohup draft run-helper-sidecar --config_path "$config_path" --root_path "$root_path" --root_domain "$root_domain" --sidecar_domain "$sidecar_domain" --helper_port "$helper_port" --sidecar_port "$sidecar_port" --identity "$identity" > .draft/logs/helper_sidecar.log 2>&1 & echo $! > .draft/pids/helper_sidecar.pid
8 changes: 8 additions & 0 deletions etc/start_local_dev.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/bash

config_path=$1
root_path=$2
helper_start_port=$3
sidecar_start_port=$4

nohup draft run-local-dev --config_path "$config_path" --root_path "$root_path" --helper_start_port "$helper_start_port" --sidecar_start_port "$sidecar_start_port" > .draft/logs/local_dev.log 2>&1 & echo $! > .draft/pids/local_dev.pid
2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ readme = "README.md"
license = {file = "LICENSE.md"}

dependencies=[
"ansible",
"Click",
"click-pathlib",
"websockets",
"uvicorn",
"fastapi",
"psutil",
"types-psutil",
"loguru",
"pydantic_settings",
"python-multipart",
Expand Down
16 changes: 16 additions & 0 deletions sidecar/app/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,15 @@
import os
import select
import shlex
import signal
import subprocess
import sys
from contextlib import contextmanager
from dataclasses import dataclass, field
from typing import Optional

import psutil


@dataclass
class Command:
Expand Down Expand Up @@ -71,8 +75,20 @@ def __enter__(self):
)
self.processes.append(process)

signal.signal(signal.SIGINT, self.signal_handler)
signal.signal(signal.SIGTERM, self.signal_handler)
return self.processes

def signal_handler(self, sig, _frame):
print(f"Handling signal: {sig}")
for process in self.processes:
for child in psutil.Process(process.pid).children(recursive=True):
child.terminate()
print(f"Terminating: {child}")
process.terminate()
print(f"Terminating: {process}")
sys.exit(0)

def __exit__(self, exc_type, exc_value, exc_tb):
for process in self.processes:
process.kill()
Expand Down
6 changes: 3 additions & 3 deletions sidecar/app/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@
)


@app.get("/")
async def root():
return {"message": "Hello World"}
@app.get("/status")
async def status():
return {"status": "up"}
2 changes: 1 addition & 1 deletion sidecar/app/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ def gen_path(v: Any) -> Path:
return Path(v)


# pyre-ignore: https://pyre-check.org/docs/errors/#dataclass-like-classes
class Settings(BaseSettings):
root_path: Annotated[Path, BeforeValidator(gen_path)]
config_path: Annotated[Path, BeforeValidator(gen_path)]
Expand All @@ -32,4 +31,5 @@ def helpers(self):
return self._helpers


# pyre-ignore: https://pyre-check.org/docs/errors/#dataclass-like-classes
settings = Settings()
Loading

0 comments on commit c3cc92d

Please sign in to comment.