Saturday, August 29, 2015

Azure VPN – ACL confusion clarified



Azure currently only supports VPN connections with static routing. For such a simple set up, there is a surprising amount of confusion in documentation, and with vendor support. Given the lack of clarification found on the internet, this may help a few others.

Similar to AWS, during Azure VPN deployment, a sample configuration template can be downloaded, which can be modified to use on your own devices. For the route-based VPN configuration, the downloaded template, as well as those shown in official documentation, like this sample Azure VPN template, includes the definition of an ACL like this:


As a network engineer will notice, the ACL is defined, but never used. When asking Azure team, the answer got back was “the template has worked for other customers”. What they said turned out to be true, here are explanations for those who care for how things really work.

First, there are two different types of VPN connections, the table below compare the two side by side (for technical details refer to excellent illustrations by packetlife.net). Here we use the Route-based VPN, which Azure refers to as “Dynamic routing”. This, by the way, is an incorrect term. Because only the establishment of VPN is dynamic, no dynamic routing like BGP is supported with Azure at the moment. More importantly, Route-based VPN does not require an ACL, while Policy-based VPN does.

VPN type
Policy-based
Route-based
Microsoft term
static routing
dynamic routing
Require ACL
yes
no
Detailed explanation and configuration



For the Route-based VPN (or Azure’s “dynamic routing”) option, Microsoft’s documentation and Azure generated configuration includes an ACL but not using it, was the source of confusion. This also explains why it still works for other customers, the ACL is simply not used. Therefore, it is recommended that the ACL be removed, to avoid further confusion to your support and operational teams.

It’s puzzling such a basic mistake remains uncorrected for so long, any network engineers at Microsoft?

Saturday, August 22, 2015

AWS ECS – data persistency test


To experiment with container services, I created a 2-container Wordpress app to run on AWS ECS
  •  The first container “mysql” runs a mysql image from docker hub, and creates a database for use by WorkPress app
  •  The second container “wordpress” runs a WordPress image from docker hub. It has a link to “mysql” container since the app needs to access its database. In addition, the container defines port mapping which maps its port 80 to port 80 on the host, thus making the app available.
It works nicely. ECS is fast. I can get a WordPress app up and running in minutes, available on the internet. However, when I stop and restart the service, all configuration and content is lost. This is expected, since by default, container data is not persistent.

ECS supports data persistency by way of container volumes. In container definition, the volume is mounted to the “containerPath” which is the content to be preserved. In volume definition, “sourcePath” references a location on the host to store the volume data. With volume backed by sourcePath, even if the containers are shut down, the app data on container volume is preserved.

In the sample 2-container WordPress app, the database container saves app database in /var/lib/mysql to /ecs/database on the host, the app container saves app configuration in /var/www/html to /ecs/config on the host.
Volume name
sourcePath (stored location on host)
containerPath (stored content on container)
vol-database
/ecs/database
/var/lib/mysql
vol-config
/ecs/config
/var/www/html

Initially this feature didn’t work. When configured from the GUI, the sourcePath variable was not taken, and no error was given. I posted on the forum. If it was a bug, it has since been corrected. When containers get restarted, the content of the blog is preserved. It is a simple and powerful technique for preserve data with apps on ECS.








Attached JSON code for the 2-container WordPress app.

{

  "family": "ECS-webapp-test-persistency",

  "containerDefinitions": [

    {

      "name": "mysql",

      "image": "seanxwang/mysqlwp:v1",

      "cpu": 10,

      "memory": 300,

      "entryPoint": [],

      "environment": [

        {

          "name": "MYSQL_DATABASE",

          "value": "wordpress"

        },

        {

          "name": "MYSQL_PASSWORD",

          "value": "wordpresspwd"

        },

        {

          "name": "MYSQL_USER",

          "value": "wordpress"

        },

        {

          "name": "MYSQL_ROOT_PASSWORD",

          "value": "wordpressdocker"

        }

      ],

      "command": [],

      "portMappings": [],

      "volumesFrom": [],

      "links": [],

      "mountPoints": [

        {

          "sourceVolume": "vol-data",

          "containerPath": "/var/lib/mysql",

          "readOnly": false

        }

      ],

      "essential": true

    },

    {

      "name": "wordpress",

      "image": "seanxwang/wordpress:v1",

      "cpu": 10,

      "memory": 300,

      "entryPoint": [],

      "environment": [],

      "command": [],

      "portMappings": [

        {

          "hostPort": 80,

          "containerPort": 80,

          "protocol": "tcp"

        }

      ],

      "volumesFrom": [],

      "links": [

        "mysql"

      ],

      "mountPoints": [

        {

          "sourceVolume": "vol-config",

          "containerPath": "/var/www/html",

          "readOnly": false

        }

      ],

      "essential": true

    }

  ],

  "volumes": [

    {

      "name": "vol-data",

      "host": {

        "sourcePath": "/ecs/database"

      }

    },

    {

      "name": "vol-config",

      "host": {

        "sourcePath": "/ecs/config"

      }

    }

  ]

}
 

Saturday, July 25, 2015

AWS automation – lessons with Cron set up

I spent quite a bit of time on what appeared to be a rather simple problem to solve, I figured posting it may save others time and frustration. This may appear trivial to a Linux admin, but these days we have people from various backgrounds, wrestling with scripts, Python, DevOps, and infrastructure as code in the “cloud” – it’s nice to share some common lessons along the way. 

I have some “monkey” jobs, which are Python scripts that runs from servers in AWS. To perform regular monitoring, generate custom CloudWatch metric, and raise alarms via SNS, Cron seems like a natural method.

But this is where I got the unexpected glitch. Python scripts runs like a charm from the command line, but Cron does not. The crontab job runs at specified interval (as seen in /var/log/cron), but no metric was received by CloudWatch. Unfortunately, this is where my Google search mislead to wrong directions (due to various posts about crontab misbehavior).  I’ve tried a number of things with no success, including running Cron as root, even rebuilding server.

Finally, I got back on track by focusing on getting more output from the job. Use the following to direct output to log file, note “2>&1” indicates that the standard error (2>) is redirected to the same file 
Crontab –
* * * * * /home/ec2-user/monkey.sh > /home/ec2-user/cron.log 2>&1

Among the output received, the message “socket.timeout: timed out” was clear indication of some sort of network problem. At that point, it is pretty obvious that it is an internet access issue - Cron does not pick up proxy setting.

There was another twist as I tried to set proxy for crontab. I tried setting environment variables in /etc/crontab, which is not supported for proxy. I then went on a detour to set proxy inside Python, way too complicated and unnecessary. It then occurred to me, all that is needed is to set proxy as the first step in crontab job. The last piece of the puzzle is to execute everything in one line (so it is one job run sequentially), like this
Crontab –
* * * * * source /etc/profile.d/proxy.sh & /home/ec2-user/monkey.sh > /dev/null 2>&1

The above job runs every minute, it sets up proxy first, and then does some monkey business.