diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index d44dd00060d68ca69050f0a9f804c3b49e5d4c65..93239ec9439a51bb34c6de7a0c5ec718e9ea5fa5 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -72,7 +72,6 @@ Python 3.6 Conda:
   - export SUMPY_NO_CACHE=1
   - export SUMPY_FORCE_SYMBOLIC_BACKEND=symengine
   - CONDA_ENVIRONMENT=.test-conda-env-py3.yml
-  - REQUIREMENTS_TXT=.test-conda-env-py3-requirements.txt
   - curl -L -O -k https://gitlab.tiker.net/inducer/ci-support/raw/master/build-and-test-py-project-within-miniconda.sh
   - ". ./build-and-test-py-project-within-miniconda.sh"
   tags:
@@ -105,7 +104,6 @@ Flake8:
 Benchmarks:
   script:
   - CONDA_ENVIRONMENT=.test-conda-env-py3.yml
-  - REQUIREMENTS_TXT=.test-conda-env-py3-requirements.txt
   - PROJECT=sumpy
   - PYOPENCL_TEST=portable
   - curl -L -O -k https://gitlab.tiker.net/inducer/ci-support/raw/master/build-and-benchmark-py-project.sh
diff --git a/.test-conda-env-py3-requirements.txt b/.test-conda-env-py3-requirements.txt
deleted file mode 100644
index 45c20c1f8b09a6a20cc232eb0e1ce05eb69aa403..0000000000000000000000000000000000000000
--- a/.test-conda-env-py3-requirements.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-git+https://gitlab.tiker.net/inducer/boxtree
-git+https://github.com/inducer/pymbolic
-git+https://github.com/inducer/loopy
diff --git a/.test-conda-env-py3.yml b/.test-conda-env-py3.yml
index a696dc8de72fdf5d00e90ea9a326efdc3c2d019b..ec8e85a0c326825e40067f8791e238b10bf403e9 100644
--- a/.test-conda-env-py3.yml
+++ b/.test-conda-env-py3.yml
@@ -3,6 +3,7 @@ channels:
 - inducer
 - conda-forge
 - defaults
+
 dependencies:
 - git
 - conda-forge::numpy
@@ -13,4 +14,9 @@ dependencies:
 - python=3.6
 - symengine=0.3.0
 - python-symengine=0.3.0
-# things not in here: loopy boxtree pymbolic pyfmmlib
+
+- pip
+- pip:
+    - git+https://gitlab.tiker.net/inducer/boxtree
+    - git+https://github.com/inducer/pymbolic
+    - git+https://github.com/inducer/loopy
diff --git a/README.rst b/README.rst
index 1f6e76d1584fbdfd2075d965b492507a742c92a0..884bef17cbaea4675daced30e117881e603fb7dd 100644
--- a/README.rst
+++ b/README.rst
@@ -2,9 +2,14 @@ sumpy: n-body kernels and translation operators
 ===============================================
 
 .. image:: https://gitlab.tiker.net/inducer/sumpy/badges/master/pipeline.svg
-   :target: https://gitlab.tiker.net/inducer/sumpy/commits/master
+    :alt: Gitlab Build Status
+    :target: https://gitlab.tiker.net/inducer/sumpy/commits/master
+.. image:: https://dev.azure.com/ak-spam/inducer/_apis/build/status/inducer.sumpy?branchName=master
+    :alt: Azure Build Status
+    :target: https://dev.azure.com/ak-spam/inducer/_build/latest?definitionId=17&branchName=master
 .. image:: https://badge.fury.io/py/sumpy.png
-    :target: http://pypi.python.org/pypi/sumpy
+    :alt: Python Package Index Release Page
+    :target: https://pypi.org/project/sumpy/
 
 Sumpy is mainly a 'scaffolding' package for Fast Multipole and quadrature methods.
 If you're building one of those and need code generation for the required Multipole
@@ -32,4 +37,4 @@ Resources:
 * `source code via git <http://github.com/inducer/sumpy>`_
 
 If you can see inside the UIUC firewall, you may browse
-`benchmark results <http://koelsch.d.tiker.net/benchmarks/asv/sumpy/>`_.
\ No newline at end of file
+`benchmark results <http://koelsch.d.tiker.net/benchmarks/asv/sumpy/>`_.
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
new file mode 100644
index 0000000000000000000000000000000000000000..68588d42a434ae4a9eeec18be985a676573b7aa0
--- /dev/null
+++ b/azure-pipelines.yml
@@ -0,0 +1,66 @@
+jobs:
+-
+    job: 'Python2'
+    pool:
+        vmImage: 'ubuntu-latest'
+
+    steps:
+    -
+        script: |
+            set -e
+            sed 's/python=3/python=2.7/' .test-conda-env-py3.yml > .test-conda-env-py2.yml
+            cat .test-conda-env-py2.yml
+            CONDA_ENVIRONMENT=.test-conda-env-py2.yml
+            curl -L -O -k https://gitlab.tiker.net/inducer/ci-support/raw/master/build-and-test-py-project-within-miniconda.sh
+            . ./build-and-test-py-project-within-miniconda.sh
+
+        displayName: 'Pytest Conda'
+    -
+        task: PublishTestResults@2
+        inputs:
+            testResultsFormat: 'JUnit'
+            testResultsFiles: 'test/pytest.xml'
+
+-
+    job: 'Python3'
+    pool:
+        vmImage: 'ubuntu-latest'
+
+    steps:
+    -
+        script: |
+            set -e
+            CONDA_ENVIRONMENT=.test-conda-env-py3.yml
+            curl -L -O -k https://gitlab.tiker.net/inducer/ci-support/raw/master/build-and-test-py-project-within-miniconda.sh
+            . ./build-and-test-py-project-within-miniconda.sh
+
+        displayName: 'Pytest Conda'
+
+    -
+        task: PublishTestResults@2
+        inputs:
+            testResultsFormat: 'JUnit'
+            testResultsFiles: 'test/pytest.xml'
+
+-
+    job: 'Flake8'
+    pool:
+        vmImage: 'ubuntu-latest'
+    strategy:
+        matrix:
+            Python37:
+                python.version: '3.7'
+
+    steps:
+    -
+        task: UsePythonVersion@0
+        inputs:
+            versionSpec: '$(python.version)'
+
+    -
+        script: |
+            set -e
+            curl -L -O -k https://gitlab.tiker.net/inducer/ci-support/raw/master/prepare-and-run-flake8.sh
+            . ./prepare-and-run-flake8.sh sumpy test
+
+        displayName: 'Flake8'