Category: Uncategorized

Junior Consultant Qualities

I spent last night in Mexico City speaking to and recruiting Dreamers that have been in a coding bootcamp at <hola-code/>, powered by Hack Reactor,  for the past four months. Many without previous technology experience at all. In that time, they more competent than many that have been in the industry anywhere in the world. I was asked what two qualities were the most important for junior consultants. Without a doubt I settled on curioustity and flexibility.

Curiosity – You must always be wondering what’s next, how it works, how it can be better. Like the early humans that wondered what was over the mountains or across the water.

Flexibility – You must be able to adapt to changing circumstances like team skills and experience, technical requirements, functional requirements, costs, timelines, and most importantly different roles and responsibilities.

Important Languages for Azure

I am in Mexico City this week and spent a lot of time with recent college graduates. They are going through training and getting imersed in the Mobiik culture. They primarily know C# and many asked what languages were important to learn. So, even though Azure has expanded its capabilities, I feel this list represents a balance of not being too many languages with what is truly necessary to be productive. This list is in order or importance to me:

  1. C# – Duh, right? Do I even need to explain this entry? The core to most applications running in Azure will use C#.
  2. JavaScript – Most apps are Web Apps and mobile apps. JavaScript plays in both worlds in addition to the backend for the those Node.js fans.
  3. PowerShell – How do you get those apps in Azure in an automated way? How do automate your environment once the app is deployed? How do you analyze your use and consumption?
  4. Ruby – If you have a large IaaS solution in Azure or any cloud for that matter, you are going to want to deploy a configuration management solution like Puppet or Chef, which are both written in Ruby and knowing Ruby really helps with their development.
  5. Bash – The popularity of deploying Linux in Azure is growing. If you are going to adopt Linux, then Bash skills are definitely required.

It is a polyglot world these days; 1 & 2 are for the development of the app itself, 3 & 4 for managing the apps lifecycle, and 5 for well-roundedness. Once you’ve tackled these, start to look at Python, Java, and Groovy as part of the next set to learn. Embrace development as development and don’t get hung up on one language or environment.

NGINX Docker Container Reverse Proxy

SonarQube dropped native support for HTTPS, so you need to stand it up behind a reverse proxy to serve up SSL. This same procedure can be used to secure anything behind SSL like Jenkins, Confluence, Jira, etc. The other cool thing with this approach is that you can gain higher density in low volume environments by running multiple containers on one host. For example, I access my home instances with the following URLs:

They are all containers running on a single host, reverse proxied by NGINX. This allows me to not have to remember what port a given app is running on and is much cleaner.

So, today I am going to show how to run SonarQube in a docker container and expose it to the outside world through NGINX running in another container.


For this implementation, I will be adding config file along with the certificate and key file in the NGINX image. For the SonarQube image we will be setting enviroment variables. Therefore, we need the following 5 files available on the Docker host:

  1. sonarqube.env – This is a key value pair file for the environment variables.
  2. sonarqube.crt – This is the fullchain SSL certificate.
  3. sonarqube.key – This is the private key.
  4. default.conf – This is the default site configuration file for NGINX.
  5. docker-compose.yaml – This is the docker-compose file to bring everything up easy.

The sonarqube.env looks sort of like this:


The NGINX default.conf file is a straight forward reverse proxy config. We redirect port 80 to 443 for HTTPS and proxy_pass to the container name and the appropriate 9000 port.

server {
 listen 80;
 listen [::]:80;


 return 301 https://$server_name$request_uri;

server {
  listen 443 ssl;
  listen [::]:443 ssl;


  ssl_certificate /etc/ssl/certs/sonarqube.crt;
  ssl_certificate_key /etc/ssl/private/sonarqube.key;

  access_log /var/log/nginx/sonarqube.access.log;

  location / {
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-SSL on;
    proxy_set_header X-Forwarded-Host $host;
    proxy_pass http://sonarqube_container:9000;
    proxy_redirect off;

For the docker-compose file, we require version 3.5 of the format for setting the user defined network name. I am setting it to proxy_net in this example. Docker has deprecated links so this is the preferred way to get containers to communicate and resolve each other using their container names.

version: "3.5"

    container_name: sonarqube_container
    image: sonarqube
      - proxy_net
    restart: always
      - "9000"
      - sonarqube.env

    container_name: reverse_proxy
      - sonarqube_container
    image: nginx
      - proxy_net
      - 80:80
      - 443:443
    restart: always
      - /etc/madridcentral/default.conf:/etc/nginx/conf.d/default.conf
      - /etc/madridcentral/sonarqube.crt:/etc/ssl/certs/sonarqube.crt
      - /etc/madridcentral/sonarqube.key:/etc/ssl/private/sonarqube.key

  name: proxy_net

Now we can use the following command to bring it all up:

docker-compose up -d

We should see something similar to the following:


Packer Ubuntu Boot Command

I’ve seen lots of examples on the Internet of Ubuntu installer boot commands for use in Packer. They appear to be derived from the same source and that’s fine, but they aren’t optimized and some comments about what are required are inaccurate. There are two reasons to minimize the boot command:

  1. Time – It takes time to enter the boot command over the VNC connection even if it automated. This affects the fix/test cycle time.
  2. Duplication – Options in the boot command can be specified in the preseed file. You either need to update both spots of wonder which value will be taken.

This is the command I use:

"boot_command": [
" initrd=/install/initrd.gz",
" auto=true",
" priority=critical",
" url=http://{{ .HTTPIP }}:{{ .HTTPPort }}/{{user `preseed_path`}}",
I believe this to be the absolute minimal Ubuntu install boot command for Packer. I minimize the use of <wait> to speed the process. For the options I do supply, I use the shortened alias to speed the process as well. The use of auto=true defers the keyboard and locale questions to after the preseed file is loaded by the installer and priority=critical suppresses remaining questions that will eventually be answered in the preseed file like hostname.
A couple of other items, make sure you use the Alternative CD image and not the Live CD and boot your VM using BIOS and not EFI. For Ubuntu 18.04.1 Server AMD64 use this URL:

Debugging Packer Azure-Arm Builder

Getting a Packer build run to complete successfully can be challenging. Getting the write combination of template configuration and scripts is always a challenge. If you stuck trying to get here are a few tips.

Turn on Logging

Enable Packer logging by setting a few environment variables. Set PACKER_LOG = 1 and enter a file path for PACKER_LOG_PATH.

Prevent Cleanup on Error

Inform Packer that it should ask you what to do when it encounters an error instead of just immediately cleaning up all the resources it created.

packer build -on-error=ask mytemplate.json

Log into VM

If examining the log file isn’t enough to resolve the issue, you can leverage our ability to prevent cleanup and log into the VM. So, what is the password? Well the password is not dumped into the console output, which is just fine. You need to open the file at the path you specified for PACKER_LOG_PATH. Once you have that open you can search for “adminPassword” and grab the value that immediately follows it.


Simple HTTP file hosting with NGINX

I am doing a lot of Packer lately building images for deployment in Azure. Rather than copy content or worry about accessing SMB or NFS shares, I decided to expose my file server to make downloading original ISO files easy. However, I struggled a bit to find the right NGINX configuration to make this happen. So, if you ever find yourself in need of hosting files to download with NGINX you can use this configuration as a starting point:

server {
    listen 80;
    listen [::]:80;

    location /software {
        autoindex on;
        alias /storage/standard/software;
        types { application/octet-stream; }
        default_type application/octet-stream;

This is good for ngnix/1.12.1 (Ubuntu) on Ubuntu 17.10 (Artful Aardvark)

ConEmu Tiling

I’m constantly on the command line for Git, PowerShell, NodeJs, SSH, etc. I’ve been using ConEmu for a while to consolidate all my terminals into a single window with tabs, which is great. However, sometimes you want to see multiple terminals at the same time. ConEmu has a great feature for that. One thing, I am constantly doing is using a bash shell for ssh and copying information from a PowerShell session.


To get your setup in a similar fashion, add a Startup Task in ConEmu and specify the following commands:

powershell -new_console:d:C:\Git
bash -new_console:sH
powershell -new_console:d:C:\Git -new_console:sV