+ - 0:00:00
Notes for current slide
Notes for next slide

Continuous Delivery in Government

DevOps fundamentals for the public sector

Aidan Feldman, Civic Technologist

Setup

  1. Go to Visual Studio Online: online.visualstudio.com
  2. Sign in, or create a Microsoft+Azure account if needed
1 / 50

Intros

2 / 50

Exercise

3 / 50

What's your agency's Dev[Sec]Ops maturity?

4 / 50

What's your level of Dev[Sec]Ops experience?

5 / 50

What we're going to accomplish*

  • Setting up a development environment in Visual Studio Online
  • Running an application "locally"
  • Automated application testing
  • Deploying to infrastructure-as-a-service (IaaS)
  • Deploying to a platform-as-a-service (PaaS)
  • Automated security testing
  • Continuous integration (CI)

*If we're lucky

6 / 50

Disclaimers

  • Please ask questions
    • If you have one, someone else is probably thinking the same thing
  • We are using Azure, but this is not an endorsement
    • Could use any number of cloud providers
  • You will need a credit/debit card
    • Just for verification; shouldn't cost anything
7 / 50

Setup

  1. Go to Visual Studio Online
  2. Sign in, or create a Microsoft+Azure account if needed
  3. Create a Billing Plan
  4. Create an Environment, using a Git repository of afeld/delivery
  5. Click the Environment to Connect
  6. Open a terminal
9 / 50

Visual Studio Online

To run the app from Visual Studio Online:

  1. Go into the application directory

    cd app
  2. Install dependencies.

    pip3 install -r requirements.txt --user
10 / 50

Run the app

  1. Start the app server.

    flask run
  2. It should say Running on http://127.0.0.1:5000/

  3. In the Activity Bar (on the left), click the Remote Explorer
  4. Under Environment Details, then Forwarded Ports, click Port :5000

This should open a new browser tab that says "Hello, World!"

11 / 50

Speed check

12 / 50

Automated testing

Run the tests:

pytest test_local.py
13 / 50

Test-driven development (TDD) assignment

  1. Add a test for a new route: /bye should return Goodbye!
  2. Run the tests again

    pytest test_local.py
  3. Get the test to pass

14 / 50

Infrastructure-as-a-service (IaaS)

  1. Go to Create a Virtual Machine (VM)
  2. Fill in the Basics
    • Resource group: Create new, then enter vm-manual
    • Virtual machine name: workshop
    • Username: vsonline
    • SSH public key:
      1. From terminal, run cat ~/.ssh/id_rsa.pub
      2. Copy the output (ssh-rsa through vsonline)
      3. Paste into input field
    • Select inbound ports: Select HTTP and SSH
    • Leave the rest as defaults
  3. Click Review + create
  4. Click Create
15 / 50

SSH

  1. Click Go to resource
  2. Copy the Public IP address
    • Don't close the tab
  3. From the terminal, run ssh <IP>

The prompt should change to vsonline@workshop:~$.

16 / 50

Deploy

  1. Install dependencies

    sudo apt-get update && sudo apt-get install -y python3-flask
  2. Get the app code

    git clone --depth=1 https://github.com/afeld/delivery.git
  3. Go into the app directory

    cd delivery/app
17 / 50

Deploy (continued)

  1. Start the app server

    sudo FLASK_APP=app.py flask run -h 0.0.0.0 -p 80
  2. Go back to your Azure Portal tab

  3. Copy the Public IP address
  4. Open a new browser tab
  5. Paste the IP into the URL bar
  6. Press return
18 / 50

What did we do?

  1. Created a virtual machine
  2. Provided an SSH key
  3. SSH'd in
  4. Installed dependencies
  5. Downloaded the app code
  6. Started the server
19 / 50

What didn't we do?

  • Configure HTTPS
  • Ensure high availability
  • Ensure that operating system packages stay up-to-date
  • Harden the SSH configuration
  • Set up logging
  • ...
20 / 50

Exit

  1. Press CONTROL+c
  2. Type exit and press return

Your prompt should change back to vsonline:~/workspace.

21 / 50

How long would it take you to recreate?

22 / 50

Why might that be a problem?

23 / 50

Why might that be a problem?

  • Creating new environments (staging)
  • Migration
  • Accidental deletion
  • Security incidents
24 / 50

Break?

25 / 50

Infrastructure as code

Setting up the Azure-level stuff.

  1. Log into the Azure CLI

    az login
26 / 50

Infrastructure as code, continued

  1. Go into the terraform/ directory

    cd terraform
  2. Initialize Terraform

    terraform init
  3. Create the infrastructure

    terraform apply
27 / 50

Configuration as code

  • Setting up the virtual machine-level stuff
  • We'll use Ansible, but Chef, Puppet, etc. are equivalent configuration management tools
28 / 50

Configuration as code

  1. Go to the ansible/ directory

    cd ../ansible
  2. Configure the virtual machine via Ansible playbook

    ansible-playbook -i vms.azure_rm.yml init.yml
29 / 50

Idempotency

  1. Run Terraform again:

    cd ../terraform
    terraform apply
  2. What happened?

  3. Visit the public_ip in your browser
  4. Run Ansible again

    cd ../ansible
    ansible-playbook -i vms.azure_rm.yml init.yml
  5. What happened?

30 / 50

Why is infrastructure/configuration as code a good idea?

31 / 50

Why is infrastructure/configuration as code a good idea?

  • Consistency/repeatability
  • Auditability
  • Automate-ability
  • Unlike documentation, keeps itself up-to-date
32 / 50

Break?

33 / 50

Azure App Services

Roughly following the Python Quickstart.

34 / 50

Deploy

  1. Deploy the application

    cd ../app
    az webapp up \
    --sku F1 \
    --name <yourname>-test
  2. It should output a URL. Copy to a new browser tab, and you should see "Hello, World!"

  3. Try going to the https:// version of that same URL
35 / 50

View logs

  1. Tail the logs

    az webapp log tail
  2. In your tab with the web page open, hit refresh

  3. Look at the log output in your terminal
36 / 50

What did we do?

  1. Ran a single command
  2. Fin.
37 / 50

What didn't we do?

  • Configure HTTPS
  • Ensure high availability
  • Ensure that operating system packages stay up-to-date
  • Harden the SSH configuration
  • Set up logging
  • ...

...because all are done for us.

38 / 50

Microsoft cloud model comparison

39 / 50

Security tests

  1. Open test_security.py
  2. Modify the HOST to be your deployed app
  3. Run the tests

    pytest test_security.py
40 / 50

Making security tests pass

  1. Force HTTPS

    az webapp update --https-only true
  2. Run the tests again

    pytest test_security.py
41 / 50

Continuous integration (CI)

  1. Sign up / sign in to github.com
    • Free plan is fine
  2. From the workshop repository, click Use this template
  3. For Repository name, put in delivery (anything, really)
  4. Click Create repository from template
  5. On your newly created repository, click the Actions tab
  6. You should see the build running
42 / 50

Continuous integration (CI) assignment

Get Bandit to run against your repository. Do so by editing .github/workflows/workflow.yml through GitHub.

A clue: see how run is being used.

43 / 50

Why is continuous integration a good idea?

44 / 50

Why is continuous integration a good idea?

  • Consistency/repeatability
  • Auditability
  • Automate-ability
  • Unlike documentation, keeps itself up-to-date
45 / 50

Cleanup*

To ensure you don't get charged for anything:

  1. View all resources
  2. Select all
  3. Delete

*You can keep them if you like, but that's on you.

46 / 50

What we did

  • Set up a development environment
  • Ran an application "locally"
  • Automated application testing
  • Deployed to infrastructure-as-a-service (IaaS)
  • Deployed to a platform-as-a-service (PaaS)
  • Automated security testing
47 / 50

General principles

  • Do less
  • Leverage platforms
  • Automate
  • Get skills in-house
48 / 50

Intros

2 / 50
Paused

Help

Keyboard shortcuts

, , Pg Up, k Go to previous slide
, , Pg Dn, Space, j Go to next slide
Home Go to first slide
End Go to last slide
Number + Return Go to specific slide
b / m / f Toggle blackout / mirrored / fullscreen mode
c Clone slideshow
p Toggle presenter mode
t Restart the presentation timer
?, h Toggle this help
Esc Back to slideshow