Skip to content

Commit

Permalink
large sweep for 0.12.2 compatibility and crushing some issues
Browse files Browse the repository at this point in the history
  • Loading branch information
syntaqx committed Jun 24, 2019
1 parent ab3fad5 commit 7c56b38
Show file tree
Hide file tree
Showing 10 changed files with 258 additions and 210 deletions.
96 changes: 49 additions & 47 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -1,50 +1,52 @@
version: 2
version: 2.1
aliases:
- &setup_remote_docker
setup_remote_docker:
version: 18.09.3
docker_layer_caching: true
- &docker_login
run: echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_LOGIN" --password-stdin
executors:
buildpack:
environment:
IMAGE_NAME: $CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME
TF_VERSION: 0.12.2
docker:
- image: circleci/buildpack-deps
jobs:
build:
working_directory: /build
docker:
- image: docker:17.05.0-ce-git
executor: buildpack
steps:
- checkout
- *setup_remote_docker
- *docker_login
- run: docker build -t $IMAGE_NAME .
- run: docker save -o image.tar $IMAGE_NAME
- persist_to_workspace:
root: .
paths:
- ./image.tar
release:
executor: buildpack
steps:
- checkout
- setup_remote_docker
- run:
name: Install dependencies
command: |
apk add --no-cache \
py-pip=9.0.0-r1
pip install \
docker-compose==1.12.0
- restore_cache:
keys:
- v1-{{ .Branch }}
paths:
- /caches/app.tar
- run:
name: Load Docker image layer cache
command: |
set +o pipefail
docker load -i /caches/app.tar | true
- run:
name: Build application Docker image
command: |
docker build --cache-from=app -t 28mm/blast-radius .
- run:
name: Save Docker image layer cache
command: |
mkdir -p /caches
docker save -o /caches/app.tar 28mm/blast-radius
- save_cache:
key: v1-{{ .Branch }}-{{ epoch }}
paths:
- /caches/app.tar
- run:
name: Run tests
command: |
true
- deploy:
name: Push application Docker image
command: |
if [ "${CIRCLE_BRANCH}" == "master" ]; then
docker login -u $DOCKER_LOGIN -p $DOCKER_PASSWORD
docker push 28mm/blast-radius
fi
- attach_workspace:
at: /tmp/workspace
- *setup_remote_docker
- *docker_login
- run: docker load -i /tmp/workspace/image.tar
- run: docker tag $IMAGE_NAME $IMAGE_NAME:$TF_VERSION
- run: |-
docker push $IMAGE_NAME:latest
docker push $IMAGE_NAME:$TF_VERSION
workflows:
version: 2
builder:
jobs:
- build
- release:
requires:
- build
filters:
branches:
only: master
4 changes: 4 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.*
doc
providers/
LICENSE
59 changes: 14 additions & 45 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,53 +1,22 @@
#Dockerfile to encapsulate both terraform and blast-radius
#
#How-to build docker image (from working-directory having blast-radius source)
# docker build -t blast-radius .
#
#How-to run docker container (from working-directory having *.tf files)
# By default, the --serve arg is passed internally to blast-radius
#
# Syntax to run in foreground (to stop: ^C):
# docker run -it --rm -p 5000:5000 -v $(pwd):/workdir blast-radius
#
# Syntax to run detached (to stop: docker rm -f blast1):
# docker run -d --name blast1 -p 5000:5000 -v $(pwd):/workdir blast-radius
ARG TF_VERSION=0.12.2
ARG PYTHON_VERSION=3.7

#Implementation notes
# Using ubuntu (rather than alpine) base image due to problems with graphviz fonts on alpine
FROM hashicorp/terraform:$TF_VERSION AS terraform

FROM ubuntu:18.04
FROM python:$PYTHON_VERSION-alpine
RUN pip install -U pip ply \
&& apk add --update --no-cache graphviz ttf-freefont

#define default terraform version in environment var
ENV TF_VERSION "0.12.0"
COPY --from=terraform /bin/terraform /bin/terraform
COPY ./docker-entrypoint.sh /bin/docker-entrypoint.sh
RUN chmod +x /bin/docker-entrypoint.sh

#expose blast-radius port
EXPOSE 5000

#install graphviz and py dependencies
RUN apt-get update \
&& apt-get install -y \
curl \
git \
graphviz \
python3 \
python3-pip \
jq \
unzip \
&& rm -rf /var/lib/apt/lists/*

#install terraform
WORKDIR /src
COPY . .
RUN chmod +x ./docker-build.sh \
&& ./docker-build.sh /src

#create blast-radius package from source
RUN pip3 install -e .
RUN pip install -e .

#set up entrypoint script
RUN chmod +x ./docker-entrypoint.sh
VOLUME ["/data"]
WORKDIR /data

#set up runtime workdir for tf files
WORKDIR /workdir
ENTRYPOINT ["/src/docker-entrypoint.sh"]
CMD ["--serve"]
ENTRYPOINT ["/bin/docker-entrypoint.sh"]
CMD ["blast-radius", "--serve"]
168 changes: 117 additions & 51 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,85 +1,151 @@
# Blast Radius

[![PyPI version](https://badge.fury.io/py/BlastRadius.svg)](https://badge.fury.io/py/BlastRadius) ![CircleCI](https://img.shields.io/circleci/project/github/28mm/blast-radius.svg)
[![CircleCI](https://circleci.com/gh/28mm/blast-radius/tree/master.svg?style=svg)](https://circleci.com/gh/28mm/blast-radius/tree/master)
[![PyPI version](https://badge.fury.io/py/BlastRadius.svg)](https://badge.fury.io/py/BlastRadius)

*Blast Radius* is a tool for reasoning about *Terraform* dependency graphs with interactive visualizations. Use *Blast Radius* to:
* **Learn** about *Terraform* or one of its cloud providers, through [example configurations](https://28mm.github.io/blast-radius-docs/).
* **Document** your infrastructure
* **Reason** about relationships between resources, and evaluate changes to them.
[terraform]: https://www.terraform.io/
[examples]: https://28mm.github.io/blast-radius-docs/

<img src="doc/blastradius-interactive.png">
_Blast Radius_ is a tool for reasoning about [Terraform][] dependency graphs
with interactive visualizations.

* **Interact** with this diagram (and many others) [here](https://28mm.github.io/blast-radius-docs/).
Use _Blast Radius_ to:

# Quickstart
* __Learn__ about *Terraform* or one of its providers through real [examples][]
* __Document__ your infrastructure
* __Reason__ about relationships between resources and evaluate changes to them
* __Interact__ with the diagram below (and many others) [in the docs][examples]

Install *Blast Radius* with pip, and *Graphviz* through your system's package manager.
![screenshot](doc/blastradius-interactive.png)

````bash
[...]$ pip3 install BlastRadius
[...]$ brew install graphviz
````
## Prerequisites

Point *Blast Radius* at an `init-ed` *Terraform* project, and connect with your browser.
* [Graphviz](https://www.graphviz.org/)
* [Python](https://www.python.org/) 3.7 or newer

```bash
[...]$ blast-radius --serve /path/to/terraform-project
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
> __Note:__ For macOS you can `brew install graphviz`
## Quickstart

The fastest way to get up and running with *Blast Radius* is to install it with
`pip` to your pre-existing environment:

```sh
pip install blastradius
```

Once installed just point *Blast Radius* at any initialized *Terraform*
directory:

```sh
blast-radius --serve /path/to/terraform/directory
```

And you will shortly be rewarded with a browser link http://127.0.0.1:5000/.

## Docker
*Alternatively*, you can launch *Blast Radius* in a docker container. (In this example, the current working directory contains a *Terraform* project.)

```bash
[...]$ docker run --security-opt apparmor:unconfined --cap-add=SYS_ADMIN -it --rm -p 5000:5000 -v $(pwd):/workdir:ro 28mm/blast-radius
[privileges]: https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities
[overlayfs]: https://wiki.archlinux.org/index.php/Overlay_filesystem

To launch *Blast Radius* for a local directory by manually running:

```sh
docker run --rm -it -p 5000:5000 \
-v $(pwd):/data:ro \
--security-opt apparmor:unconfined \
--cap-add=SYS_ADMIN \
28mm/blast-radius
```

*Please note*: because terraform saves module links as _absolute_ paths in _.terraform/modules/<uuid>_ we mount the host's filesystem read-only and force terraform to update the modules path at start. This way we don't interfere with the real project. Thus docker has to be run with the `--cap-add=SYS_ADMIN` flag to use the [overlayFS](https://wiki.archlinux.org/index.php/Overlay_filesystem) see [Docker's documentation](https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities).
A slightly more customized variant of this is also available as an example
[docker-compose.yml](./examples/docker-compose.yml) usecase for Workspaces.

### Docker configurations

*Terraform* module links are saved as _absolute_ paths in relative to the
project root (note `.terraform/modules/<uuid>`). Given these paths will vary
betwen Docker and the host, we mount the volume as read-only, assuring we don't
ever interfere with your real environment.

However, in order for *Blast Radius* to actually work with *Terraform*, it needs
to be initialized. To accomplish this, the container creates an [overlayfs][]
that exists within the container, overlaying your own, so that it can operate
independently. To do this, certain runtime privileges are required --
specifically `--cap-add=SYS_ADMIN`.

For more information on how this works and what it means for your host, check
our the [runtime privileges][privileges] documentation.

*Additional note*:
If you organised your terraform directories with stacks and modules, please call *Blast Radius* from the root directory and give the stack's directory as argument (plus the `--serve` argument).
#### Docker & Subdirectories

```bash
[...]$ tree -d
/-- project
|-- modules
If you organized your *Terraform* project using stacks and modules,
*Blast Radius* must be called from the project root and reference them as
subdirectories -- don't forget to prefix `--serve`!

For example, let's create a Terraform `project` with the following:

```txt
$ tree -d
`-- project/
|-- modules/
| |-- foo
| |-- bar
| `-- dead
`-- stacks
`-- beef
`-- stacks/
`-- beef/
`-- .terraform
```

[...]$ cd project
docker run --cap-add=SYS_ADMIN -it --rm -p 5000:5000 -v $(pwd):/workdir:ro 28mm/blast-radius --serve stacks/beef
It consists of 3 modules `foo`, `bar` and `dead`, followed by one `beef` stack.
To apply *Blast Radius* to the `beef` stack, you would want to run the container
with the following:

```sh
$ cd project
$ docker run --rm -it -p 5000:5000 \
-v $(pwd):/data:ro \
--security-opt apparmor:unconfined \
--cap-add=SYS_ADMIN \
28mm/blast-radius --serve stacks/beef
```
# Embedded Figures

You may wish to embed figures produced with *Blast Radius* in other documents. You will need the following:
## Embedded Figures

You may wish to embed figures produced with *Blast Radius* in other documents.
You will need the following:

1. an `svg` file and `json` document representing the graph and its layout.
2. `javascript` and `css` found in `.../blastradius/server/static`
3. a uniquely identified DOM element, where the `<svg>` should appear.
1. An `svg` file and `json` document representing the graph and its layout.
2. `javascript` and `css` found in `.../blastradius/server/static`
3. A uniquely identified DOM element, where the `<svg>` should appear.

Further details available [here](doc/embedded.md).
You can read more details in the [documentation](docs/embedeed.md)

# Implementation Details
## Implementation Details

*Blast Radius* uses the [*Graphviz*](http://graphviz.org/) package to layout graph diagrams, [*PyHCL*](https://github.com/virtuald/pyhcl) to parse [*Terraform*](https://www.terraform.io/) configurations, and [*d3.js*](https://d3js.org/) to implement interactive features and animations.
*Blast Radius* uses the [Graphviz][] package to layout graph diagrams,
[PyHCL](https://github.com/virtuald/pyhcl) to parse [Terraform][] configuration,
and [d3.js](https://d3js.org/) to implement interactive features and animations.

# Further Reading
## Further Reading

The development of *Blast Radius* is documented in a series of [blog](https://28mm.github.io) posts:
The development of *Blast Radius* is documented in a series of
[blog](https://28mm.github.io) posts:

* [part 1](https://28mm.github.io/notes/d3-terraform-graphs): motivations, d3 force-directed layouts vs. vanilla graphviz.
* [part 2](https://28mm.github.io/notes/d3-terraform-graphs-2): d3-enhanced graphviz layouts, meaningful coloration, animations.
* [part 3](https://28mm.github.io/notes/terraform-graphs-3): limiting horizontal sprawl, supporting modules.
* [part 4](https://28mm.github.io/notes/d3-terraform-graphs-4): search, pan/zoom, prune-to-selection, docker.
* [part 1](https://28mm.github.io/notes/d3-terraform-graphs): motivations, d3 force-directed layouts vs. vanilla graphviz.
* [part 2](https://28mm.github.io/notes/d3-terraform-graphs-2): d3-enhanced graphviz layouts, meaningful coloration, animations.
* [part 3](https://28mm.github.io/notes/terraform-graphs-3): limiting horizontal sprawl, supporting modules.
* [part 4](https://28mm.github.io/notes/d3-terraform-graphs-4): search, pan/zoom, prune-to-selection, docker.

A catalog of example *Terraform* configurations, and their dependency graphs can be found [here](https://28mm.github.io/blast-radius-docs/).
A catalog of example *Terraform* configurations, and their dependency graphs
can be found [here](https://28mm.github.io/blast-radius-docs/).

* [AWS two-tier architecture](https://28mm.github.io/blast-radius-docs/examples/terraform-provider-aws/two-tier/)
* [AWS networking (featuring modules)](https://28mm.github.io/blast-radius-docs/examples/terraform-provider-aws/networking/)
* [Google two-tier architecture](https://28mm.github.io/blast-radius-docs/examples/terraform-provider-google/two-tier/)
* [Azure load-balancing with 2 vms](https://28mm.github.io/blast-radius-docs/examples/terraform-provider-azurem/2-vms-loadbalancer-lbrules/)
* [AWS two-tier architecture](https://28mm.github.io/blast-radius-docs/examples/terraform-provider-aws/two-tier/)
* [AWS networking (featuring modules)](https://28mm.github.io/blast-radius-docs/examples/terraform-provider-aws/networking/)
* [Google two-tier architecture](https://28mm.github.io/blast-radius-docs/examples/terraform-provider-google/two-tier/)
* [Azure load-balancing with 2 vms](https://28mm.github.io/blast-radius-docs/examples/terraform-provider-azurem/2-vms-loadbalancer-lbrules/)

These examples are drawn primarily from the `examples/` directory distributed with various *Terraform* providers, and aren't necessarily ideal. Additional examples, particularly demonstrations of best-practices, or of multi-cloud configurations strongly desired.
These examples are drawn primarily from the `examples/` directory distributed
with various *Terraform* providers, and aren't necessarily ideal. Additional
examples, particularly demonstrations of best-practices, or of multi-cloud
configurations strongly desired.
Loading

0 comments on commit 7c56b38

Please sign in to comment.