Community

Preparing your Windows 10 dev environment for use with the Syntropy Stack

NOIA | 02.23| 20

Photo by Christina @ wocintechchat.com on Unsplash

This guide is a follow-up from my previous post showing you how to set up your Mac dev environment for working with the Syntropy Stack.

Preparing your Mac OS dev environment for use with the Syntropy Stack

In it, I stressed the importance of taking the time to set up your dev environment properly as it saves you time in the long run by eliminating the need to perform certain repetitive tasks (among other things). Working with the Syntropy Stack on Windows is a little different, so this version will cover the following:

  • Creating an agent token through your Syntropy Stack account
  • Install Windows Subsystem for Linux (WSL)
  • Installing Python ≥ 3.6
  • Installing Syntropy CLI & Syntropy NAC
  • Authentication
  • Installing Ansible and the Syntropy Ansible Collection
  • Working with git repos and WSL
  • Setting up Virtual Machines in the cloud
  • SSH Keys

Create an Agent Token

Your Agent Token is the API key you’ll use with your Syntropy Agents so that they can authenticate and join the Syntropy Ecosystem. You can generate an Agent Token using the Syntropy UI. If you’d don’t already have a Syntropy Stack account, you can request access via their website. Once you’re able to login, click the dropdown next to your username and select Agent tokens.

Creating an Agent Token via Syntropy UI

Click [+] New Agent Token to create your token. I like to create one token per project. This way, if your credentials are somehow leaked, you can destroy that project token without it affecting any other networks that might be online. Remember to change the Expiration date as it defaults to the current day, meaning that if you leave it as is, the token will be invalid the following day.

Change the Agent Token’s expiration date

Install Windows Subsystem for Linux (WSL)

I’ll assume that you have at least some familiarity with Linux given that you’ll be working with the Syntropy Stack and Linux VMs. However, if not, well then there’s no time like the present to start learning!

Windows isn’t always an inherently developer-friendly operating system... though admittedly that depends on what languages and frameworks you’re working with. The tools we’ll be using (namely ansible and the Syntropy CLI) tend to play nice with Linux, so we’ll install the Windows Subsystem for Linux (WSL) to get the best of both worlds. WSL is aimed at developers who want to run a GNU/Linux environment (like us!). You can read more about it here if you’re interested in doing a deeper dive. In short, it’s basically providing us with a Linux virtual environment without us having to go through the trouble of setting up our own VM using something like VirtualBox. Here’s how to set it up on your Windows machine.

In the search bar, start typing in “turn windows features on or off”

Turn windows features on and off

Select Windows Subsystem for Linux and press ‘OK’. Feel free to reboot your machine if it prompts you to do so.

Open the Microsoft Store (you can search “Microsoft Store” from the search bar). Search for Ubuntu and click ‘Get’.

Install Ubuntu from the Microsoft Store

When the installation is complete, click “Launch” and create a new Linux username and password when prompted to do so.

Now that we have our Linux environment set up, let’s install some packages.

Installing Python ≥ 3.6

The latest version of Ubuntu ( 20.04.1 LTS ) comes with python3 pre-installed. Check that you have it installed using:

~$ python3 --version
Python 3.8.2

Unfortunately, it doesn’t come packaged with pip3 (Python3's package manager) pre-installed, so we’ll need to install it ourselves. But first, let’s update the package lists and upgrade the existing packages on the system (this could take a minute or two).

`sudo apt update -y && sudo apt upgrade -y`

Now we’re ready to install pip3.

sudo apt install python3-pip -y

Let’s check the version to make sure everything worked as expected:

~$ pip3 --version
pip 20.0.2 from /usr/lib/python3/dist-packages/pip (python 3.8)

Everything’s looking good so far, let’s move on to installing the Syntropy CLI.

Installing Syntropy CLI & Syntropy NAC

We’ll mostly be using two separate utilities that form part of the CLI, syntropyctl (Computational Topology Library) and syntropynac (Network As Code) utilities. There’s more information in the Syntropy Stack documentation should you need it. We can install them using:

pip3 install syntropycli && pip3 install syntropynac

You’ll need to source your ~/.profile to make sure the utilities that have just been installed to ~/.local/bin (which is referenced in your PATH) are available to your current terminal session. There’s a useful explanation of the difference between .profile , .bash_profile , and .bashrc here.

~$ source ~/.profile

As a final step, we need to add that SYNTROPY_API_SERVER to our system’s ENV (environment variables). You can use vim (or nano if you’re not comfortable with vim). Copy and paste the following into your ~/.bashrc file.

export SYNTROPY_API_SERVER=https://controller-prod-server.syntropystack.com

Remember to source the ~/.bashrc file once you’re finished editing it to ensure the new environment variable is available to your current terminal session.

source ~/.bashrc

Authentication

Before we get into authentication, here’s a handy tip for working with the Ubuntu terminal in Windows. Click the Ubuntu icon located at the top-left of the window (far-left of the toolbar).

Select Properties and check the Use Ctrl+Shift+C/V as Copy/Paste box.

Select Ctrl+Shift_V/V as Copy/Paste

This is helpful because “QuickEdit mode” is enabled by default — this means that right-clicking is a shortcut for paste and, as such, you won’t be able to copy text from the terminal using the right-click context menu. In addition, Ctrl+C(the Windows shortcut for copy), is overridden by the Linux terminal’s Ctrl+C which kills a process with the SIGINT signal, so again we can’t copy text. Instead, we’re now able to uses a combination of Ctrl+Shift+Cto copy and Ctrl+Shift+vto paste. You’ll see why this is helpful in a second…

Now we need to generate an API token that allows us to authenticate our CLI commands. Doesn’t confuse the API Token (generated using the CLI) with the Agent Token (An API key generated using the Syntropy UI).

Generate an API Token by logging in using the CLI (the SYNTROPY_API_SERVER needs to be present in your ENV for this to succeed ):

syntropyctl login <your_syntropystack_username> <your_syntropystack_password>
Generate an API Token

This command will output an alphanumeric string (ie. your API token). Copy the API token this command outputs and add it to your system’s ENV variables. Copy and paste this (remember the Ctrl+Shift+C trick), as well as your username and password, and place them into your ~/.bashrc alongside the SYNTROPY_API_SERVER variable.

~$ vim ~/.bashrc

And add the following:

export SYNTROPY_API_SERVER=https://controller-prod-server.syntropystack.com
export SYNTROPY_API_TOKEN=”your_syntropy_api_token”
export SYNTROPY_PASSWORD=”your_syntropy_password”
export SYNTROPY_USERNAME=”your_syntropy_username”

Remember to again source the file from your current terminal window so that the variables are available to your current session.

Installing Ansible and the Syntropy Ansible Galaxy Collection

Ansible is the simplest way to automate apps and IT infrastructure. Application Deployment + Configuration Management + Continuous Delivery.

We’ll use Ansible to configure our host VMs, install necessary dependencies, deploy our agents and services, and even create our networks. Installing Ansible is simple and can be done using Python’s pip3 package manager. Ansible has great documentation, so definitely check it out if you’re curious about what it’s capable of, or if you aren’t sure about what something’s doing. We’ll be using the Syntropy Ansible Galaxy Collection. Ansible Galaxy houses content created by the Ansible community. Collections contain useful playbooks, roles and modules for us to include in our own playbooks.

First, let’s install Ansible.

pip3 install ansible

Check that the installation completed successfully.

syntropy@DESKTOP-Q47GK91:~$ ansible --version
ansible 2.10.5
config file = None
configured module search path = ['/home/syntropy/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /home/syntropy/.local/lib/python3.8/site-packages/ansible
executable location = /home/syntropy/.local/bin/ansible
python version = 3.8.5 (default, Jul 28 2020, 12:59:40) [GCC 9.3.0]

You should have the latest version installed, but if it’s lower than `2.9`, you’ll want to manually install a higher version. Eg.

pip3 install ansible===2.9.17

The next thing we want to do is create a global config file. To make the log output from your Ansible CLI easier to read, create an Ansible config file and place it in your home directory.

$ vim ~/.ansible.cfg

And add the following to it (make sure the ansible_python_interpreter is set to the result of your which Python3 command output):

~$ which python3
/usr/bin/python3

Add this to your file:

~/.ansible.cfg
[defaults]
stdout_callback=yaml
# use stdout_callback when running adhoc commands too
bin_ansible_callbacks = True
interpreter_python = auto_silent
remote_tmp = /tmp/ansible-$USER
ansible_python_interpreter = /usr/bin/python3

Without the config, your log output looks like this:

TASK [create_docker_network : Create Docker network] *****************************************************************
ok: [broker] => {"ansible_facts": {"docker_network": {"Attachable": false, "ConfigFrom": {"Network": ""}, "ConfigOnly": false, "Containers": {"1893dcb898d5299c5dd9cf5a2219f2e2f08956507afc56d86bfe64cb96e18837": {"EndpointID": "7b9ec7d78666c965795c34db03465562e4bb7f5bdfa21de71d5f69824c3b48a7", "IPv4Address": "172.20.0.2/24", "IPv6Address": "", "MacAddress": "02:42:ac:14:00:02", "Name": "mosquitto"}}, "Created": "2021-01-11T17:10:29.613448381Z", "Driver": "bridge", "EnableIPv6": false, "IPAM": {"Config": [{"Subnet": "172.20.0.0/24"}], "Driver": "default", "Options": null}, "Id": "9e6daec0c1bb385fc2d6459655602ab5ce127505e7e6eaea091c9e5af7b5a1f0", "Ingress": false, "Internal": false, "Labels": {}, "Name": "syntropynet", "Options": {}, "Scope": "local"}}, "changed": false, "network": {"Attachable": false, "ConfigFrom": {"Network": ""}, "ConfigOnly": false, "Containers": {"1893dcb898d5299c5dd9cf5a2219f2e2f08956507afc56d86bfe64cb96e18837": {"EndpointID": "7b9ec7d78666c965795c34db03465562e4bb7f5bdfa21de71d5f69824c3b48a7", "IPv4Address": "172.20.0.2/24", "IPv6Address": "", "MacAddress": "02:42:ac:14:00:02", "Name": "mosquitto"}}, "Created": "2021-01-11T17:10:29.613448381Z", "Driver": "bridge", "EnableIPv6": false, "IPAM": {"Config": [{"Subnet": "172.20.0.0/24"}], "Driver": "default", "Options": null}, "Id": "9e6daec0c1bb385fc2d6459655602ab5ce127505e7e6eaea091c9e5af7b5a1f0", "Ingress": false, "Internal": false, "Labels": {}, "Name": "syntropynet", "Options": {}, "Scope": "local"}}

After adding your config, it’ll look like this:

TASK [create_docker_network : Create Docker network] *****************************************************************
ok: [broker] => changed=false
ansible_facts:
docker_network:
Attachable: false
ConfigFrom:
Network: ''
ConfigOnly: false
Containers:
1893dcb898d5299c5dd9cf5a2219f2e2f08956507afc56d86bfe64cb96e18837:
EndpointID: 7b9ec7d78666c965795c34db03465562e4bb7f5bdfa21de71d5f69824c3b48a7
IPv4Address: 172.20.0.2/24
IPv6Address: ''
MacAddress: 02:42:ac:14:00:02
Name: mosquitto
Created: '2021-01-11T17:10:29.613448381Z'
Driver: bridge
EnableIPv6: false
IPAM:
Config:
- Subnet: 172.20.0.0/24
Driver: default
Options: null
Id: 9e6daec0c1bb385fc2d6459655602ab5ce127505e7e6eaea091c9e5af7b5a1f0
Ingress: false
Internal: false
Labels: {}
Name: syntropynet
Options: {}
Scope: local
network:
Attachable: false
ConfigFrom:
Network: ''
ConfigOnly: false
Containers:
1893dcb898d5299c5dd9cf5a2219f2e2f08956507afc56d86bfe64cb96e18837:
EndpointID: 7b9ec7d78666c965795c34db03465562e4bb7f5bdfa21de71d5f69824c3b48a7
IPv4Address: 172.20.0.2/24
IPv6Address: ''
MacAddress: 02:42:ac:14:00:02
Name: mosquitto
Created: '2021-01-11T17:10:29.613448381Z'
Driver: bridge
EnableIPv6: false
IPAM:
Config:
- Subnet: 172.20.0.0/24
Driver: default
Options: null
Id: 9e6daec0c1bb385fc2d6459655602ab5ce127505e7e6eaea091c9e5af7b5a1f0
Ingress: false
Internal: false
Labels: {}
Name: syntropynet
Options: {}
Scope: local

That induces much less anxiety! By placing the .ansible.cfg file in your home directory ( ~/ ), you’re making it global. You can place an additional .ansible.cfg in your project root and it will override any settings that overlap with the global config.

Next, let’s install the galaxy collection:

ansible-galaxy collection install syntropynet.syntropy

Navigate to your local ansible directory where the collection has been installed:

cd ~/.ansible/collections/ansible_collections/syntropynet/syntropy

and install the requirements (you’ll see some, if not most, were already installed along with the CLI).

pip3 install -U -r requirements.txt

Working with git repos and WSL

While your Linux subsystem has its own file system, it makes the full windows system drive available to you at the /mnt/c directory at the root of your file system.

Windows is files are available via /mnt/c

This is great news as any code or config files we edit in our IDE (eg. Ansible playbooks) will be accessible through our Linux terminal. As en example, let’s clone the syntropy-devops-integrations repo to the Windows desktop (remember to substitute out <your_windows_user> for your own Windows user).

$ cd /mnt/c/Users/<your_windows_user>/Desktop
$ git clone https://github.com/SyntropyNet/syntropy-devops-integrations.git
...
$ cd syntropy-devops-integrations/

You’re all set to work on your local repo!

Setting up Virtual Machines in the cloud

Each VM you run should be on a separate cloud provider’s infrastructure. You can use any cloud provider currently supported by the Syntropy Stack. Check their documentation for a complete list. Using different providers isn’t an absolute requirement, but we do this to help illustrate the flexibility, interoperability, and ease of use when working with the Syntropy Stack across the expanse of the internet. The most important thing is that your VMs don’t share a public IP address. So, if you don’t want to use three separate cloud providers, try placing your VMs in different geographic regions. The most important thing is that they don’t share a public IP address. I have 3 basic VMs from Digital Ocean, GCP, and AWS. I used these providers as I already have accounts with them and am familiar with their services. that I chose to set up my VMs as follows:

FluentD: Digital Ocean, Type: Basic, 1vCPU, 1GB memory, OS: Ubuntu 20.04

Elasticsearch: Google Cloud Platform, Type: e2-micro, 2vCPU, 1GB memory, OS: Ubuntu 20.04

Kibana: AWS, Type: t2-micro, 1vCPU, 1GB memory, OS: Ubuntu 18.04

All three of these options are in the same price range (around $5–6/month) and are sufficient for the purposes of this example.

Setting up each VM on a particular cloud provider is beyond the scope of this post, but I’ve included some links to guides below to help get you started if you’re not sure how to go about creating the VMs. You’ll want to add your SSH public key so you can access your VMs from the terminal using SSH. I’d recommend installing Ubuntu as your OS to ensure the commands I share translate directly. But of course, if you’re comfortable with other flavours of Linux, by all means, have at it. The fact that the Syntropy Stack leverages docker means that we’re distro agnostic!

SSH Keys

As a personal preference, I prefer to create separate SSH key-pairs for different projects or tasks, depending on their scope. For example, I have a dedicated syntropy_rsa keypair that I use with all of my Syntropy VMs.

If you want to create a new key-pair, you can use the following command. The -N flag just creates a key-pair without a passphrase, which is useful for certain automated tasks (like GitHub workflows, for example). The "user@host" is just a way of identifying the keypair. Feel free to use something like syntropy@local .

$ ssh-keygen -t rsa -b 4096 -C "user@host" -q -N ""
Enter file in which to save the key (/Users/craig/.ssh/id_rsa): /Users/<user>/.ssh/syntropy_rsa

Next you’ll want to authorize your new key on your VMs. Add your new public key to each of your hosts authorized_keys file. You can do this from your local dev machine’s command line. The <host> will be your VM’s public IP and the <user> will be the Linux username for that VM. For example, on AWS the EC2’s default user is always ubuntu .

Eg.

~$ ssh-copy-id -i ~/.ssh/syntropy_rsa.pub <user>@<host> -f

You can also do this manually if you don’t have ssh-copy-id available. Just SSH into your VM and add the public key to the ~/.ssh/authorized_keys file. You can copy your public key to the clipboard using:

cat ~/.ssh/syntropy_rsa.pub

And copying the output. Just bear in mind that, depending on your cloud provider, you’ll probably have to add your SSH public key via their UI/console before you’ll have SSH access. For example, on Digital Ocean, you need to add your public key via Settings > Security.

Adding an SSH public key to Digital Ocean

The final thing you may need to check is that port 22 is open to inbound traffic. Again, depending on your cloud provider, you may have to manually set this or configure a firewall to allow inbound traffic on port 22. Here’s an example of configuring my network firewall on Digtial Ocean under Networking > Firewalls > Rules.

Setting inbound rules on a Digital Ocean firewall

That’s it, you’re ready to start building with the Syntropy Stack on your Windows machine!


Preparing your Windows 10 dev environment for use with the Syntropy Stack was originally published in Syntropy on Medium, where people are continuing the conversation by highlighting and responding to this story.

Comment 0

delete

Are you sure you want to delete this post?