Skip to content

Commit

Permalink
Robust Bootstrapping (#85)
Browse files Browse the repository at this point in the history
  • Loading branch information
osterman authored and const-bon committed Nov 10, 2017
1 parent 45335a1 commit 7a96a6d
Show file tree
Hide file tree
Showing 15 changed files with 205 additions and 123 deletions.
13 changes: 6 additions & 7 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
FROM alpine:3.4
FROM alpine:3.6

RUN apk update \
&& apk add unzip curl tar \
python make bash vim jq figlet \
openssl openssh-client sshpass iputils drill \
gcc libffi-dev python-dev musl-dev openssl-dev py-virtualenv \
git coreutils less groff bash-completion && \
mkdir /etc/bash_completion.d/
mkdir -p /etc/bash_completion.d/ /etc/profile.d/

RUN echo "net.ipv6.conf.all.disable_ipv6=0" > /etc/sysctl.d/00-ipv6.conf

Expand Down Expand Up @@ -139,12 +139,9 @@ RUN curl --fail -sSL -o /usr/local/bin/gomplate https://github.com/hairyhenderso

# Install AWS Assumed Role
ENV AWS_ASSUMED_ROLE_VERSION 0.1.0
RUN mkdir -p /etc/profile.d \
&& curl --fail -sSL -o /etc/profile.d/aws-assume-role.sh https://raw.githubusercontent.com/cloudposse/aws-assumed-role/0.1.0/profile \
RUN curl --fail -sSL -o /etc/profile.d/aws-assume-role.sh https://raw.githubusercontent.com/cloudposse/aws-assumed-role/0.1.0/profile \
&& chmod +x /etc/profile.d/aws-assume-role.sh

ENV BOOTSTRAP=true

ENV BANNER "geodesic"

# Where to store state
Expand All @@ -158,9 +155,11 @@ ENV MOTD_URL=http://geodesic.sh/motd
ENV HOME=/mnt/local

VOLUME ["/mnt/local"]
VOLUME ["/mnt/remote"]

ADD rootfs/ /

WORKDIR /mnt/local

ENTRYPOINT ["/bin/bash", "-l"]
ENTRYPOINT ["/bin/bash"]
CMD ["-c", "bootstrap"]
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ build:
@make --no-print-directory docker:build

install:
@REQUIRE_PULL=false public/install.sh
@docker run --rm -e CLUSTER=galaxy $(DOCKER_IMAGE_NAME) | sudo bash -s dev

run:
@geodesic
70 changes: 30 additions & 40 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,59 +53,49 @@ Docker can be easily installed by following the instructions for your OS:

## Quick Start

1. Install the geodesic client, if you haven't already: (feel free to inspect the shell script!)
1. `export CLUSTER=test.example.com`

2. Create a new project

This will create a new project in your current working directory, complete with a `Dockerfile`, `Makefile` file.

```
curl -s https://geodesic.sh | sudo bash
docker run -e CLUSTER \
-e DOCKER_IMAGE=cloudposse/${CLUSTER} \
-e DOCKER_TAG=dev \
cloudposse/geodesic:latest -c new-project | tar -xv -C .
```
2. Create a `Dockerfile` that defines your environment

2. Customize project as necessary. Edit the `Dockerfile` to reflect your settings. The files are installed to the `$CLUSTER/` folder.
```
cd $CLUSTER
```
FROM cloudposse/geodesic:0.2.0
# Default AWS Profile name
ENV AWS_DEFAULT_PROFILE=ops
# Prefix of the cluster
ENV CLUSTER_PREFIX=aws
# Parent zone for the cluster
ENV CLUSTER_DNS_ZONE=example.com
# AWS Region for the cluster
ENV AWS_REGION=us-west-2
# AWS Region of the S3 bucket to store cluster configuration
ENV CLUSTER_STATE_BUCKET_REGION=us-west-2
# Username for connecting to the cluster via SSH
ENV SSH_USERNAME=admin
# Kubernetes Master EC2 instance type (optional, required if the cluster uses Kubernetes)
ENV KOPS_MASTER_SIZE=t2.medium
# Kubernetes Node EC2 instance type (optional, required if the cluster uses Kubernetes)
ENV KOPS_NODE_SIZE=t2.medium
# Kubernetes node count (Node EC2 instance count) (optional, required if the cluster uses Kubernetes)
ENV KOPS_NODE_COUNT=3
# Place configuration in 'conf/' directory
COPY conf/ /conf/

WORKDIR /conf/
3. Initialize the project
```
make init
```

3. Build your cluster image
4. Build the docker container
```
make docker:build
```

5. Install the wrapper shell
```
docker build -t aws.example.com
make install
```

6. Run the shell: `/usr/local/bin/$CLUSTER`

## Creating a Kops Cluster

4. Run `geodesic use --name=aws.example.com` to start the geodesic shell for that cluster
5. Run `cloud create` to run through configuration steps
6. Run `cloud up` to provision the cluster
Create your `kops` cluster from a manifest. The manifest template is located in `/templates/kops/default.yaml` and is compiled by running `build-kops-manifest`

After building the manifest, create the cluster by running and following the resultant instructions.
```
kops create -f /conf/kops/manifest.yml
```

All done. Your cloud is now up and running.

Expand Down
33 changes: 0 additions & 33 deletions contrib/Dockerfile.example

This file was deleted.

8 changes: 0 additions & 8 deletions rootfs/etc/profile.d/0.bootstrap.sh

This file was deleted.

2 changes: 2 additions & 0 deletions rootfs/templates/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
These are a collection of `gomplate` formatted templates

32 changes: 19 additions & 13 deletions public/install.sh → rootfs/templates/bootstrap
Original file line number Diff line number Diff line change
@@ -1,44 +1,50 @@
#!/bin/bash
DOCKER_IMAGE=${DOCKER_IMAGE:-cloudposse/geodesic}
DOCKER_TAG=${DOCKER_TAG:-$1}
APP_NAME=${APP_NAME:-geodesic}
INSTALL_PATH=${INSTALL_PATH:-/usr/local/bin}
OUTPUT=${OUTPUT:-/dev/null} # Replace with /dev/stdout to audit output
REQUIRE_PULL=${REQUIRE_PULL:-true}
export DOCKER_IMAGE={{getenv "DOCKER_IMAGE" "cloudposse/geodesic"}}
export DOCKER_TAG={{getenv "DOCKER_TAG" "${1:-dev}"}}
export APP_NAME=${APP_NAME:-`basename $DOCKER_IMAGE`}
export INSTALL_PATH=${INSTALL_PATH:-/usr/local/bin}
export INSTALLER_NAME="${APP_NAME}-installer"
export OUTPUT=${OUTPUT:-/dev/null} # Replace with /dev/stdout to audit output
export REQUIRE_PULL=${REQUIRE_PULL:-false}

if [ -z "${DOCKER_IMAGE}" ]; then
echo "Docker image cannot be empty" >&2
exit 1
fi

if [ -z "${DOCKER_TAG}" ]; then
DOCKER_TAG=latest
fi

if [ "${GEODESIC_SHELL}" == "true" ]; then
echo "Installer cannot be run from inside a geodesic shell"
echo "Installer cannot be run from inside a geodesic shell" >&2
exit 1
fi

# Check if docker is installed
which docker >/dev/null
if [ $? -ne 0 ]; then
echo "Docker is required to run ${APP_NAME}"
echo "Docker is required to run ${APP_NAME}" >&2
exit 1
fi

# Check that we can connect to docker
docker ps >/dev/null 2>&1
if [ $? -ne 0 ]; then
echo "Unable to communicate with docker daemon. Make sure your environment is properly configured and then try again."
echo "Unable to communicate with docker daemon. Make sure your environment is properly configured and then try again." >&2
exit 1
fi

# Check if tee is installed
which tee >/dev/null
if [ $? -ne 0 ]; then
echo "Tee is required to install ${APP_NAME}"
echo "Tee is required to install ${APP_NAME}" >&2
exit 1
fi

# Check that we can write to install path
if [ ! -w "${INSTALL_PATH}" ]; then
echo "Cannot write to ${INSTALL_PATH}. Please retry using sudo."
echo "Cannot write to ${INSTALL_PATH}. Please retry using sudo." 2>&1
exit 1
fi

Expand All @@ -53,9 +59,9 @@ if [ "${REQUIRE_PULL}" == "true" ]; then
fi

# Sometimes docker might not exit cleanly
docker rm "${APP_NAME}-install" >/dev/null 2>&1
docker rm -f "${INSTALLER_NAME}" >/dev/null 2>&1

(docker run --name "${APP_NAME}-install" --rm --tty "${DOCKER_IMAGE}:${DOCKER_TAG}" | tee "${INSTALL_PATH}/${APP_NAME}" > ${OUTPUT}) && \
(docker run --name "${INSTALLER_NAME}" --rm -e DOCKER_IMAGE -e DOCKER_TAG "${DOCKER_IMAGE}:${DOCKER_TAG}" -c wrapper | tee "${INSTALL_PATH}/${APP_NAME}" > ${OUTPUT}) && \
chmod 755 "${INSTALL_PATH}/${APP_NAME}"

if [ $? -eq 0 ]; then
Expand Down
55 changes: 55 additions & 0 deletions rootfs/templates/scaffolding/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
FROM {{ getenv "GEODESIC_IMAGE" "cloudposse/geodesic" }}:{{ getenv "GEODESIC_TAG" "latest" }}

ENV DOCKER_IMAGE "{{ getenv "DOCKER_IMAGE" "org/geodesic.example.org" }}"
ENV DOCKER_TAG "{{ getenv "DOCKER_TAG" "latest" }}"

# Default AWS Profile name
ENV AWS_DEFAULT_PROFILE="{{ getenv "AWS_DEFAULT_PROFILE" "ops" }}"

# Prefix of the cluster
ENV CLUSTER_PREFIX="{{ getenv "CLUSTER_PREFIX" "aws" }}"

# Parent zone for the cluster
ENV CLUSTER_DNS_ZONE="{{ getenv "CLUSTER_DNS_ZONE" "example.com" }}"

# AWS Region for the cluster
ENV AWS_REGION="{{ getenv "AWS_REGION" "us-west-2"}}"

# AWS Region of the S3 bucket to store cluster configuration
ENV CLUSTER_STATE_BUCKET_REGION="{{ getenv "CLUSTER_STATE_BUCKET_REGION" "us-west-2"}}"

# Username for connecting to the cluster via SSH
ENV SSH_USERNAME="{{ getenv "SSH_USERNAME" "admin" }}"

# Install kops
ENV KOPS_STATE_STORE "{{ getenv "KOPS_STATE_STORE" "s3://undefined" }}"
ENV KOPS_STATE_STORE_REGION "{{ getenv "KOPS_STATE_STORE_REGION" "us-east-1" }}"

# https://github.com/kubernetes/kops/blob/master/channels/stable
# https://github.com/kubernetes/kops/blob/master/docs/images.md
ENV KOPS_BASE_IMAGE="{{ getenv "KOPS_BASE_IMAGE" "kope.io/k8s-1.7-debian-jessie-amd64-hvm-ebs-2017-07-28" }}"
ENV KOPS_DNS_ZONE "${CLUSTER_DNS_ZONE}"
ENV KOPS_BASTION_PUBLIC_NAME="{{ getenv "KOPS_BASTION_PUBLIC_NAME" "bastion" }}"
ENV KOPS_PRIVATE_SUBNETS="{{ getenv "KOPS_PRIVATE_SUBNETS" "172.20.32.0/19,172.20.64.0/19,172.20.96.0/19,172.20.128.0/19" }}"
ENV KOPS_UTILITY_SUBNETS="{{ getenv "KOPS_UTILITY_SUBNETS" "172.20.0.0/22,172.20.4.0/22,172.20.8.0/22,172.20.12.0/22" }}"

# Instance sizes
ENV BASTION_MACHINE_TYPE "{{ getenv "BASTION_MACHINE_TYPE" "t2.medium" }}"

# Kubernetes Master EC2 instance type (optional, required if the cluster uses Kubernetes)
ENV MASTER_MACHINE_TYPE "{{ getenv "MASTER_MACHINE_TYPE" "t2.medium" }}"

# Kubernetes Node EC2 instance type (optional, required if the cluster uses Kubernetes)
ENV NODE_MACHINE_TYPE "{{ getenv "NODE_MACHINE_TYPE" "t2.medium" }}"

# Kubernetes node count (Node EC2 instance count) (optional, required if the cluster uses Kubernetes)
ENV NODE_MAX_SIZE "{{ getenv "NODE_MAX_SIZE" "2" }}"
ENV NODE_MIN_SIZE "{{ getenv "NODE_MIN_SIZE" "2" }}"


# Place configuration in 'conf/' directory
COPY conf/ /conf/

WORKDIR /conf/

RUN build-kops-manifest
25 changes: 25 additions & 0 deletions rootfs/templates/scaffolding/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
export CLUSTER ?= $(shell basename `pwd`)
export DOCKER_ORG ?= {{ getenv "DOCKER_ORG" "cloudposse" }}
export DOCKER_IMAGE ?= $(DOCKER_ORG)/$(CLUSTER)
export DOCKER_TAG ?= dev
export DOCKER_IMAGE_NAME ?= $(DOCKER_IMAGE):$(DOCKER_TAG)
export DOCKER_BUILD_FLAGS =

-include $(shell curl -sSL -o .build-harness "https://git.io/build-harness"; echo .build-harness)

all: init deps build install run

deps:
@exit 0

build:
@make --no-print-directory docker:build

push:
docker push $(DOCKER_IMAGE)

install:
@docker run --rm $(DOCKER_IMAGE_NAME) | sudo bash -s dev

run:
$(CLUSTER)
Empty file.
Loading

0 comments on commit 7a96a6d

Please sign in to comment.