Skip to content

Commit

Permalink
Added bastion configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
ravbaba committed Nov 5, 2015
1 parent e72a344 commit 229db03
Show file tree
Hide file tree
Showing 22 changed files with 489 additions and 112 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*.tfstate*
*.tfvars
*.tfplan
*.ovpn
packer_cache
packer/build
packer/*.pem
Expand All @@ -17,3 +18,4 @@ inventory/terraform.py
tests/spec/*/*runtime_spec.rb
contrib-plugins/*
terraform/*/.terraform
terraform/azure/ssh_thumbprint
11 changes: 7 additions & 4 deletions bootstrap/azure/config-default.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@ export ATLAS_TOKEN=${ATLAS_TOKEN:?"Need to set ATLAS_TOKEN non-empty"}
export ATLAS_INFRASTRUCTURE=${ATLAS_INFRASTRUCTURE:-capgemini/apollo}

export TF_VAR_azure_settings_file=${TF_VAR_azure_settings_file:?"Need to set TF_VAR_azure_settings_file non-empty"}
export TF_VAR_user=${TF_VAR_user:?"Need to set User non-empty"}
export TF_VAR_username=${TF_VAR_username:?"Need to set TF_VAR_username non-empty"}
export TF_VAR_ssh_key_thumbprint=${TF_VAR_ssh_key_thumbprint:?"Need to set TF_VAR_ssh_key_thumbprint non-empty"}

export TF_VAR_key_file=${TF_VAR_key_file:-$HOME/.ssh/apollo_azure_rsa.pfx}
export TF_VAR_key_name=${TF_VAR_key_name:-apollo}

# Overrides default folder in Terraform.py inventory.
export TF_VAR_STATE_ROOT="${APOLLO_ROOT}/terraform/${APOLLO_PROVIDER}"
Expand All @@ -15,8 +18,8 @@ export ANSIBLE_SSH_ARGS="-F ${APOLLO_ROOT}/terraform/${APOLLO_PROVIDER}/ssh.conf

# Terraform mappings needs to be statically passed as -var parameters
# so no really needed to export them. Exporting for consitency.
export TF_VAR_atlas_artifact_master=${TF_VAR_atlas_artifact_master:-capgemini/apollo-ubuntu-14.04-amd64}
export TF_VAR_atlas_artifact_slave=${TF_VAR_atlas_artifact_slave:-capgemini/apollo-ubuntu-14.04-amd64}
export TF_VAR_atlas_artifact_master=${TF_VAR_atlas_artifact_master:-apollo-ubuntu-14.04-amd64-1446651919}
export TF_VAR_atlas_artifact_slave=${TF_VAR_atlas_artifact_slave:-apollo-ubuntu-14.04-amd64-1446651919}
export TF_VAR_atlas_artifact_version_master=${TF_VAR_atlas_artifact_version_master:-1}
export TF_VAR_atlas_artifact_version_slave=${TF_VAR_atlas_artifact_version_slave:-1}

Expand All @@ -25,5 +28,5 @@ export TF_VAR_master_size=${TF_VAR_master_size:-Medium}
export TF_VAR_slave_size=${TF_VAR_slave_size:-Medium}
export TF_VAR_slaves=${TF_VAR_slaves:-1}

export APOLLO_consul_dc=${APOLLO_consul_dc:-$TF_VAR_region}
export APOLLO_consul_dc=${APOLLO_consul_dc:-${TF_VAR_region// /_}}
export APOLLO_mesos_cluster_name=${APOLLO_mesos_cluster_name:-$TF_VAR_region}
89 changes: 89 additions & 0 deletions bootstrap/azure/util.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,96 @@
#!/bin/bash

# Use the config file specified in $APOLLO_CONFIG_FILE, or default to
# config-default.sh.
function set_vpn() {
while true; do
read -p "Do you want to start the VPN and setup a connection now (y/n)?" yn
case $yn in
[Yy]* ) ovpn_start;ovpn_client_config; break;;
[Nn]* ) exit;;
* ) echo "Please answer y or n.";;
esac
done
}

ansible_ssh_config() {
pushd "${APOLLO_ROOT}/terraform/${APOLLO_PROVIDER}"
export APOLLO_bastion_ip=$( terraform output bastion.ip )

# Virtual private cloud CIDR IP.
ip=$( terraform output vn_cidr_block.ip )
export APOLLO_network_identifier=$( get_network_identifier "${ip}" )

cat <<EOF > ssh.config
Host bastion $APOLLO_bastion_ip
StrictHostKeyChecking no
User ubuntu
HostName $APOLLO_bastion_ip
ProxyCommand none
IdentityFile $TF_VAR_private_key_file
BatchMode yes
PasswordAuthentication no
UserKnownHostsFile /dev/null
Host $APOLLO_network_identifier.*
StrictHostKeyChecking no
ServerAliveInterval 120
TCPKeepAlive yes
ProxyCommand ssh -q -A -F $(pwd)/ssh.config ubuntu@$APOLLO_bastion_ip nc %h %p
ControlMaster auto
ControlPath ~/.ssh/mux-%r@%h:%p
ControlPersist 30m
User ubuntu
IdentityFile $TF_VAR_private_key_file
UserKnownHostsFile /dev/null
EOF
popd
}

ssh_thumbprint() {
pushd "${APOLLO_ROOT}/terraform/${APOLLO_PROVIDER}"
if [ ! -f "ssh_thumbprint" ]; then
touch ssh_thumbprint
fi
popd
}

apollo_down() {
pushd "${APOLLO_ROOT}/terraform/${APOLLO_PROVIDER}"
terraform destroy -var "azure_settings_file=${TF_VAR_azure_settings_file}" \
-var "region=${TF_VAR_region}"
popd
}

ovpn_start() {
pushd "${APOLLO_ROOT}/terraform/${APOLLO_PROVIDER}"
echo "... initialising VPN setup" >&2
/bin/sh -x bin/ovpn-init
/bin/sh -x bin/ovpn-start
popd
}

ovpn_client_config() {
pushd "${APOLLO_ROOT}/terraform/${APOLLO_PROVIDER}"
echo "... creating VPN client configuration" >&2
/bin/sh -x bin/ovpn-new-client "${TF_VAR_user}"
/bin/sh -x bin/ovpn-client-config "${TF_VAR_user}"

# We need to sed the .ovpn file to replace the correct IP address, because we are getting the
# instance IP address not the elastic IP address in the downloaded file.
bastion_ip=$(terraform output bastion.ip)
/usr/bin/env sed -i -e "s/\([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}/${bastion_ip}/g" "${TF_VAR_user-apollo.ovpn}"

/usr/bin/open "${TF_VAR_user-apollo.ovpn}"
# Display a prompt to tell the user to connect in their VPN client,
# and pause/wait for them to connect.
while true; do
read -p "Your VPN client should be open. Please now connect to the VPN using your VPN client.
Once connected hit y to open the web interface or n to exit (y/n)?" yn
case $yn in
[Yy]* ) popd;open_urls; break;;
[Nn]* ) popd;exit;;
* ) echo "Please answer y or n.";;
esac
done
}
5 changes: 4 additions & 1 deletion bootstrap/common.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
# Util functions cloud reusable.
APOLLO_ROOT=$(dirname "${BASH_SOURCE}")/..
DEFAULT_CONFIG="${APOLLO_ROOT}/bootstrap/${APOLLO_PROVIDER}/${APOLLO_CONFIG_FILE-"config-default.sh"}"
DYNAMIC_INVENTORY="https://raw.githubusercontent.com/Capgemini/terraform.py/master/terraform.py"

if [ -f "${DEFAULT_CONFIG}" ]; then
source "${DEFAULT_CONFIG}"
fi
Expand Down Expand Up @@ -77,6 +79,7 @@ apollo_launch() {
elif [ "$@" ]; then
eval $@
else
run_if_exist "ssh_thumbprint"
get_terraform_modules
terraform_apply
run_if_exist "ansible_ssh_config"
Expand Down Expand Up @@ -142,7 +145,7 @@ ansible_playbook_run() {
get_ansible_inventory() {
pushd $APOLLO_ROOT
if [ ! -f inventory/terraform.py ]; then
curl -sS https://raw.githubusercontent.com/Capgemini/terraform.py/master/terraform.py -o inventory/terraform.py
curl -sS ${DYNAMIC_INVENTORY} -o inventory/terraform.py
chmod 755 inventory/terraform.py
fi
popd
Expand Down
122 changes: 105 additions & 17 deletions docs/getting-started-guides/azure.md
Original file line number Diff line number Diff line change
@@ -1,33 +1,121 @@
## Getting started on Microsoft Azure

settings file -
### Prerequisites

https://manage.windowsazure.com/publishsettings
1. You need an Microsoft Azure account. Visit [http://azure.microsoft.com](http://azure.microsoft.com) to get started.
2. Unfortunately the latest version of terraform doesn't fully support azure so you need to compile terraform from the master branch to get it working. Visit [https://github.com/hashicorp/terraform](https://github.com/hashicorp/terraform) to get more instruction how to do it.
3. You need to have [Python](https://www.python.org/) >= 2.7.5 installed along with [pip](https://pip.pypa.io/en/latest/installing.html).
4. You need to install Azure CLI on your machine, you can find instructions how to do it [here](https://azure.microsoft.com/en-gb/documentation/articles/xplat-cli-install/). To find out more how to connect Azure subscription
from the Azure CLI you can find it [here](https://azure.microsoft.com/en-gb/documentation/articles/xplat-cli-connect/)
Download settings file
[https://manage.windowsazure.com/publishsettings](https://manage.windowsazure.com/publishsettings)
and perform the command:

Create SSH Key thumbprint -
```
azure account import path_to_your_publishsettings_file
```

https://azure.microsoft.com/en-gb/documentation/articles/virtual-machines-linux-use-ssh-key/
Create an Azure Compatible Keys [more details you can find here](https://azure.microsoft.com/en-gb/documentation/articles/virtual-machines-linux-use-ssh-key/)

Upload SSH cert -
```
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ~/.ssh/id_rsa_azure.key -out ~/.ssh/id_rsa_azure.pem -subj '/CN=www.capgemini.com/O=Apollo./C=UK'
https://manage.windowsazure.com/#Workspaces/AdminTasks/ListManagementCertificates
openssl x509 -outform der -in ~/.ssh/id_rsa_azure.pem -out ~/.ssh/id_rsa_azure.pfx
Create a storage account -
ssh-add id_rsa_azure.key
```

https://manage.windowsazure.com/#Workspaces/StorageExtension
Upload SSH cert [https://manage.windowsazure.com/#Workspaces/AdminTasks/ListManagementCertificates](https://manage.windowsazure.com/#Workspaces/AdminTasks/ListManagementCertificates)

I named it capgeminiapollo
Create a storage account [https://manage.windowsazure.com/#Workspaces/StorageExtension](https://manage.windowsazure.com/#Workspaces/StorageExtension). I named it capgeminiapollo

Create a storage container -

https://manage.windowsazure.com/#Workspaces/StorageExtension/StorageAccount/capgeminiapollo/Containers
Create a storage container [https://manage.windowsazure.com/#Workspaces/StorageExtension/StorageAccount/capgeminiapollo/Containers](https://manage.windowsazure.com/#Workspaces/StorageExtension/StorageAccount/capgeminiapollo/Containers)

Use the storage account name from above here and named the storage container 'images'.

Packer build -
### Cluster Turnup

#### Download Apollo

##### Install from source at head
1. `git clone https://github.com/Capgemini/apollo.git`
2. `cd apollo`
3. `pip install -r requirements.txt`

#### Set config

Configuration can be set via environment variables.

All variables following the pattern "TF_VAR_" will be available for Apollo in terraform, see [https://github.com/hashicorp/terraform/pull/1621#issuecomment-100825568](https://github.com/hashicorp/terraform/pull/1621#issuecomment-100825568)

All variables following pattern "APOLLO_" will be available for Apollo in ansible.

For a full list of default config options for AWS see `bootstrap/azure/config-default.sh`

As a minimum you will need to set these environment variables -

```
export APOLLO_PROVIDER=azure
export TF_VAR_user=$USER
export TF_VAR_azure_settings_file='path_to_your_azure_setting_file'
export TF_VAR_username='ubuntu'
export ATLAS_TOKEN=your_atlas_token
export TF_VAR_ssh_key_thumbprint=~/.ssh/id_rsa_azure.pem
export TF_VAR_private_key_file=~/.ssh/id_rsa_azure.key
```

_NOTE: The value for ATLAS_TOKEN should be set to whatever you generated with your [Atlas Account](https://atlas.hashicorp.com/settings/tokens).

#### Turn up the cluster
```
/bin/bash bootstrap/apollo-launch.sh
```

NOTE: The script will provision a new VPC and a 3 node mesos master cluster for North Europe region.

It will also create a mesos slave cluster and a Bastion server for accessing the VPC via VPN and SSH.

It will then generate a local SSH config for the Bastion server and the private instances, and run an Ansible playbook to provision the cluster.

Finally it will attempt to start and configure a VPN client connection for you.

For instructions on how to configure the VPN (outside of the bootstrap script) to access the web interface of the tools see the [vpn guide](https://github.com/ravbaba/Apollo/blob/azure-provider/docs/getting-started-guides/aws/vpn.md).

#### Tearing down the cluster
```
/bin/bash bootstrap/apollo-down.sh
```

### Packer build

Follow the instructions [here](https://github.com/msopentech/packer-azure) to build the compile the packer plugin for Azure via Go and copy it to your packer install folder (normally
/usr/local/packer/) and set those variables:

```
export AZURE_SETTINGS_FILE=path_to_your_azure_publishsettings_file
export AZURE_SUBSCRIPTION_NAME='Free Trial'
export AZURE_STORAGE_ACCOUNT='capgeminiapollo'
export AZURE_STORAGE_CONTAINER='images'
export AZURE_LOCATION='North Europe'
export AZURE_SOURCE_IMAGE='Ubuntu Server 14.04.3-LTS'
export AZURE_INSTANCE_TYPE='Small'
export APOLLO_VERSION=0.2.0
```

in packer folder run the below command:

```
packer build ubuntu-14.04_amd64-azure.json
```

#### SSH'ing to your private instances

As part of `apollo-launch.sh` an SSH config file will be generated in `$APOLLO_ROOT/terraform/azure/ssh.config`.

If your master instance has a private IP of 10.0.1.11 (for example), You can SSH directly to that instance by doing the following -

Follow the instructions here https://github.com/msopentech/packer-azure to build the compile
the packer plugin for Azure via Go and copy it to your packer install folder (normally
/usr/local/packer/) and then -
```
ssh -F $APOLLO_ROOT/terraform/azure/ssh.config 10.0.1.11
```

packer build -var 'azure_settings_file=azure.publishsettings' -var 'azure_subscription_name=Free Trial' -var 'azure_storage_account=capgeminiapollo' -var 'azure_storage_container=images' -var 'azure_location=North Europe' -var 'azure_source_image=Ubuntu Server 14.04 LTS' -var 'azure_instance_type=Small' -var 'version=1.0.0' ubuntu-14.04_amd64-azure.json
This will proxy your SSH command via the Bastion server and you should land in the master private instance.
2 changes: 1 addition & 1 deletion packer/scripts/common/sshd.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ set -eu
set -o pipefail

# UseDNS is mostly useless and disabling speeds up logins
echo "UseDNS no" >> /etc/ssh/sshd_config
sed -i '$a UseDNS no' /etc/ssh/sshd_config
47 changes: 15 additions & 32 deletions packer/ubuntu-14.04_amd64-azure.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@
"azure_location": "{{env `AZURE_LOCATION`}}",
"azure_source_image": "{{env `AZURE_SOURCE_IMAGE`}}",
"azure_instance_type": "{{env `AZURE_INSTANCE_TYPE`}}",
"mesos_version": "0.22.1-1.0.ubuntu1404",
"marathon_version": "0.8.1-1.0.171.ubuntu1404",
"consul_version": "0.5.1",
"weave_version": "v0.11.2",
"mesos_version": "0.23.0-1.0.ubuntu1404",
"marathon_version": "v0.10.1",
"consul_version": "0.5.2",
"weave_version": "1.2.0",
"docker_version": "1.9.0-0~trusty",
"version": "{{env `APOLLO_VERSION`}}"
},
"builders": [{
Expand All @@ -31,47 +32,29 @@
"source": "scripts/ubuntu/upstart/",
"destination": "/tmp"
},
{
"type": "file",
"source": "tests",
"destination": "/tmp"
},
{
"type": "shell",
"environment_vars": [
"CONSUL_VERSION={{user `consul_version`}}",
"WEAVE_VERSION={{user `weave_version`}}",
"MESOS_VERSION={{user `mesos_version`}}",
"MARATHON_VERSION={{user `marathon_version`}}"
"MARATHON_VERSION={{user `marathon_version`}}",
"DOCKER_VERSION={{user `docker_version`}}"
],
"scripts": [
"scripts/ubuntu/base.sh",
"scripts/common/sshd.sh",
"scripts/ubuntu/install_docker.sh",
"scripts/ubuntu/install_mesos.sh",
"scripts/ubuntu/install_marathon.sh",
"scripts/common/install_consul.sh",
"scripts/ubuntu/install_dnsmasq.sh",
"scripts/common/install_weave.sh"
"scripts/common/install_weave.sh",
"scripts/common/serverspec.sh"
],
"execute_command": "{{ .Vars }} sudo -E -S bash -c '{{ .Path }}'"
},
{
"type": "file",
"source": "tests",
"destination": "/tmp"
},
{
"type": "shell",
"script": "scripts/common/serverspec.sh",
"execute_command": "{{ .Vars }} sudo -E -S bash -c '{{ .Path }}'"
}
],
"push": {
"name": "capgemini/apollo"
},
"post-processors": [{
"type": "atlas",
"artifact": "capgemini/apollo-ubuntu-14.04-amd64",
"artifact_type": "azure.image",
"metadata": {
"created_at": "{{timestamp}}",
"version": "{{user `version`}}+{{timestamp}}"
}
}]
]
}
Loading

0 comments on commit 229db03

Please sign in to comment.