I’m Eric Tummers, Software Architect at Statistics Netherlands, and this is how I work


My jobs description says Software Architect. I’m guiding my team through the technical hurdles and do some programming/testing/analysing myself. We follow the scrum guide and are working towards continuous integration and deployment. We do this in small steps. Every sprint we complete means the retrospective is done in the pub.

I expect the best and I give the best. Here’s the beer. Here’s the entertainment. Now have fun. That’s an order!
RasczakLocation: Sittard, NL
Current Gig: Devops Teamlead, CBS
Word that best describes how you work: Teamwork
Current mobile device: iPhone se
Current computer: MacBook 15 inch

What apps/software/tools can’t you live without? Why?

Wunderlist: work tasks, chores, groceries, planning, every task is there. I’m aware of the acquisition by Microsoft and the planned end-of-life.
Evernote: I’m a fan for years now.
Parallels 11: Running Windows on my MacBook is a must. And of course visual studio, team foundation server, build, release manager, sql server management studio, remote desktop, powershell, and some other tools I need for work.
Alfred: keyboard shortcuts for everything. I bought the powerpack and advise you to do the same. Still on v2 though.

What’s your workspace setup like?

Work at the office is on a thin client with 24 inch screen and (wired) mouse and keyboard. The desk and chair comply with all regulations. We have a great coffee machine.

dekstop_2017

My home workspace is still my Macbook 15 inch. I’ve a new setup with logitech keyboard and mouse (MX800) and Benq 24 inch monitor (BL2420PT). Nothing fancy but the extra screen space is very welcome.

What’s your best time-saving shortcut/life hack?

Timebox. Start on a task and spent the time you’ve got to get the best result. Get someone to look at it, get feedback. Then decide if the result is final or to spent some more time.

Besides your phone and computer, what gadget can’t you live without and why?

I replaced my Magellan Echo with the Garmin FR235. It has smart watch features and a optical heart rate monitor. My phone is on mute since the Garmin notifies me of everything.
My Apple Airpods. Easy to use, small and good sound. Never leave the house without them.

What everyday thing are you better at than everyone else? What’s your secret?

Learning new things. My current project lets me implement new things (joy) Also I try to learn the things I know to my team or anyone who listens.
I have a basic understanding of how things work and try to map new things on there. For the details I have a Pluralsight subscription and black belt google skills.

What do you listen to while you work?

My alarm clock plays classical music to wake me up in the morning. The car stereo plays about everything (grunge, rock, kids stories) driving to work. When I need some focus I play drum and bass on my headphones. My ringtone is still Run riot by Camo & Krooked, although it is muted since I got the Garmin.

What are you currently reading?

The Hard Thing About Hard Things. It gives an insight into the problems a CEO has and how to overcome these. I enjoyed reading it on my last vacation and plan to read it again after I finish it.

How do you recharge? What do you do when you want to forget about work?

Spending quality time with my wife and daughters. Phone on silent, no screens, no work. Mostly piggyback riding and tea parties
Also sports like running, fitness, climbing and snowboarding to keep me fit and healthy.

Fill in the blank: I’d love to see _________ answer these same questions.

DC Rainmaker (Ray) has been on my reading list for years. His reviews about sport gadgets is amazing. If you don’t know who this is I urge you to click the link. For the rest; you know why.

What’s the best advice you’ve ever received?

someecards.com - Make a shit first draft you cannot edit a blank page
I believe this is a variant on a Hemingway quote.

Is there anything else you’d like to add that might be interesting to readers?

Learn Powershell. There is so much possible with Powershell. If you can learn one thing this year pick Powershell.

Original idea from Lifehacker.com.

Posted in Uncategorized | Tagged , , , , , , , | Leave a comment

My 2019 developer and power user tools

toolbox by vectorolie / FreeDigitalPhotos.net
Below a list of tools I use today. If you’re like me, you check them out and add the ones you like to your own toolbox.

Image courtesy of vectorolie / FreeDigitalPhotos.net

Productivity

DropBox, file share/sync between computers and the internet
Powershell, the automation solution from microsoft
Microsoft Todo, task list on every platform (replaces Wunderlist)
IFTTT, automate the internet
Pocket, my preferred read later list, available on all platforms
Evernote, remember everything. I use it for my GTD technique called The secret weapon.
1Password, my password is ⌘ + \
Autohotkey, run macro’s on keyboard shortcuts like CTRL+ALT+5 types €

Development

Visual Studio 2017, the best IDE out there
Chrome, best browser today
NuGet, source of all the good in the world
Visual Studio Gallery, extend visual studio
Ghostdoc, CTRL+SHIFT+D to comment your code, that simple
Specflow, cucumber for .net for behavior driven development (BDD)
Just Decompile, see the code of .net assemblies
Fiddler, log http calls via this proxy
Wireshark, deep logging of network traffice
Notepad++, notepad on steroids
Pester, test and mock framework for PowerShell.
Seq, structured logging solution with GUI
SonarQube, we use it to automate our code reviews

Misc

ZoomIt, I use this in all my demos to zoom
Docker Desktop, host applications, just download and run, don’t install
Code Notes, A simple code snippet manager for developers

Mac

Cyberduck, connect to anything
DaisyDisk, see what is hogging your hard disk space
Type2phone, make my mac a Bluetooth keyboard for iPad or AppleTV
Handbrake, convert movies
Little snitch, monitor network traffic coming from your mac
HyperDock, preview windows from the dock
Alfred, spotlight replacement with lots of options
Parallels, the virtualisation solution for mac
Sublime Text, very complete text editor for code
Visual Studio Code, code editor for any platform
Gimp, freeware photo editor with all the bells and whistles you’ll need
Amphetamine, keep your mac awake

iPhone/iPad

Tweetbot, easy twitter client with pocket integration
Spark, handles my e-mail and offers tasks like send to evernote or pocket
Pocket, I do my reading mostly on iPhone or iPad
Duet, use your iPad as an extra screen
Lightningtalktimer, timer app that changes appearance with time passed

Some of the tools cost money, some are free, some offer paid options. If it saves you time or improves your work, why not support the developer that made it possible?

Also see My 2018 developer and power user tools post.

SaveSaveSaveSaveSaveSaveSaveSaveSaveSaveSaveSaveSaveSaveSaveSave

Posted in Tooling | Tagged | Leave a comment

EF codefirst migrations and Cloud Foundry

We’re using the hosted Cloud Foundry solution for development at http://run.pivotal.io.

octocat logo from githubSo everybody can hit the floor running I’ve created a template for using Entity Framework Codefirst migrations in a dotnet core web application hosted on Cloud Foundry.
The key aspects are:

  • database is linked service (attached resource in 12-factors)
  • migration in task (admin one-off process in 12-factors)

Image from press kit on github.com

Complete documentation with code on my EF-codefirst-migration repository on github.com

References

https://12factor.net The twelve-factor app

Posted in Development | Tagged , , , | Leave a comment

Cloud Foundry Task with dotnet app

We’re investigating the CF run-task command from the cli. This is used to execute tasks that run to completion, like database migrations or print something to the console 😉

Hello console

We’ve created a new console project. The main function will print the first command-line argument. Everybody is familiar with “hello world“.

The key to getting this to work on Cloud Foundry is the manifest.yml:

applications:
- name: hellotaskworld
  path: bin/Debug/netcoreapp2.0/
  instances: 0
  memory: 256M
  no-route: true
  buildpacks: dotnet_core_buildpack

instances: 0 makes sure the container is not started. It would crash-and-burn since the application exits after it prints to the console. Cloud Foundry wants to have continuously running applications like a webapp.
no-route: true binds no route to the application. It cannot serve web requests.
path: bin/Debug/netcoreapp2.0/ together with buildpacks: dotnet_core_buildpack pushes the assembly and leaves the dotnet runtime in the container

After a CF PUSH we can run the application with the CLI:

cf run-task hellotaskworld "dotnet ./HelloTaskWorld.dll eric" --name hello-eric-task
cf tasks hellotaskworld
id   name             state      command
3    hello-eric-task  SUCCEEDED  dotnet ./HelloTaskWorld.dll eric

To get the console output we request the logs

cf logs hellotaskworld --recent
[CELL/0] OUT Creating container
[CELL/0] OUT Successfully created container
[APP/TASK/hello-eric-task/0] OUT Hello eric!
[APP/TASK/hello-eric-task/0] OUT Exit status 0
[CELL/0] OUT Stopping instance 1dc5766e-f3f4-4b0d-9332-e1e761db911d
[CELL/0] OUT Destroying container
[CELL/0] OUT Successfully destroyed container

Success! We’ve send our message to Cloud Foundry.

Hello web

What about web applications? We will be deploying our website to Cloud Foundry and want our hello eric (or database migration, file cleanup, backups, …) to be run from that application.

With dotnet core the starting point of a web application is again the Main function. We can check the command-line arguments for our custom tokens.
❗ warning ❗ Cloud Foundry uses command-line arguments to configure the application: ./websitename –server.urls http://0.0.0.0:1234. Make sure your argument name is different/unique.

public static void Main(string[] args) {
    if (args[0] != "--name") {
        BuildWebHost(args).Run();
    } else {
        // start task and print to console
        Console.WriteLine($"Hello {args[1]}");
    }
}

The manifest is very simple since the main use case is a web application.

applications:
- name: webwithtask
  instances: 1
  memory: 256M

After a CF PUSH we can run the application with the CLI. The location of the assembly we got from the logging of the PUSH which shows the command to run

type:            web
instances:       1/1
memory usage:    256M
start command:   cd ${DEPS_DIR}/0/dotnet_publish && ./WebWithTask --server.urls http://0.0.0.0:${PORT}
     state     since                  cpu    memory         disk           details
#0   running   2019-09-06T10:24:32Z   0.0%   156K of 256M   104.2M of 1G   

Now we can start the task by adding the –name parameter to get to the else branch in the main function.

cf run-task webwithtask "cd /home/vcap/deps/0/dotnet_publish && ./WebWithTask --name eric" --name hello-eric-task
cf tasks webwithtask
id   name             state      command
1    hello-eric-task  SUCCEEDED  cd /home/vcap/deps/0/dotnet_publish && ./WebWithTask --name eric

To get the console output we request the logs

cf logs webwithtask --recent
[CELL/0] OUT Creating container
[CELL/0] OUT Successfully created container
[APP/TASK/hello-eric-task/0] OUT Hello eric
[APP/TASK/hello-eric-task/0] OUT Exit status 0
[CELL/0] OUT Stopping instance 12af1740-dec5-4975-96a8-85713102045d
[CELL/0] OUT Destroying container
[CELL/0] OUT Successfully destroyed container

Success! We’ve send our message to Cloud Foundry.

References

https://docs.cloudfoundry.org/devguide/using-tasks.html
https://github.com/cloudfoundry/dotnet-core-buildpack/issues/163
https://dotnet-cookbook.cfapps.io/core/app-startup-tasks/

Posted in Development | Tagged , | Leave a comment

Add Sql Server as user provided service in Cloud Foundry

In this post you’ll add Sql Server from Azure to a dotnet core mvc app. We presume you’ve already created the Sql Server in Azure. If not follow my post azure sql server for centralised database.

User Provided Service

A user provided service is a way to connect non-marketplace services to your cloud foundry app. The service will show up in the services tab and the connectionstring (or anything else you need) is added to the configuration.

We use the cli to add Sql Server as a user provided service and then hook it up to the core app. The connectionstring is provided by Azure on the portal. The line below is very long!

cf cups mySqlServerService -p '{"connectionstring": "Server=tcp:cfnorthwind.database.windows.net,1433;Initial Catalog=Northwind;Persist Security Info=False;User ID=eric@cfnorthwind;Password=4Pjby8$wTk;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;"}'
cf bind-service core mySqlServerService

In stratos the service is visible now

Code changes

We’re going to edit the dotnet core app.

First add some nugets:

dotnet add package Steeltoe.CloudFoundry.ConnectorCore
dotnet add package Steeltoe.Extensions.Configuration.CloudFoundryCore
dotnet restore

Then make the changes below.

In the program.cs we need to load the environment variable VCAP_SERVICES and parse it into the configuration. For this we’ll use the Steeltoe extension:

using Steeltoe.Extensions.Configuration.CloudFoundry;

public static IWebHost BuildWebHost(string[] args) =>
  WebHost.CreateDefaultBuilder(args)
         .AddCloudFoundry()
         .UseStartup<Startup>()
         .Build();

Then we need to create a SqlConnection and inject it into the IoC container. With a Steeltoe extension and the microsoft Options extension:

using System.Data.SqlClient;
using Microsoft.Extensions.Options;
using Steeltoe.Extensions.Configuration.CloudFoundry;

// Class with same property as provided in the cf cups statement
public class SqlServerInfo {
   public string Connectionstring { get; set; }
}
// Class that wraps the mySqlServerService in the cf cups statement
// Property is always called Credentials (look at the environment variables)
public class MySqlServiceOptions : AbstractServiceOptions {
   public SqlServerInfo Credentials { get; set; }
}

public void ConfigureServices(IServiceCollection services)
{
   services.AddMvc();
   // link the mySqlServerService from configuration to the class defined above
   services.ConfigureCloudFoundryService<MySqlServiceOptions>(Configuration, "mySqlServerService");
   services.AddScoped<SqlConnection>(x => {
      // retrieve the user provided service from the configuration
      var monitor = x.GetRequiredService<IOptionsMonitor<MySqlServiceOptions>>();
      var config = monitor.Get("mySqlServerService");
      return new SqlConnection(config.Credentials.Connectionstring);
   });
}

We plan to connect to Sql Server on the Contact page. The code below runs a query that returns some text (no sql objects needed) but only when the connection succeeds.

using System.Data.SqlClient;
using System.Data;

public IActionResult Contact([FromServices] SqlConnection dbConnection)
{
    var cmd = dbConnection.CreateCommand();
    cmd.CommandText = "SELECT 'hello world from sqlserver'";
    dbConnection.Open();
    ViewData["Message"] = "Your contact page. " + cmd.ExecuteScalar().ToString() ;
    dbConnection.Close();

    return View();
}

The code changes are done. Now cf push the application.
After the app is restarted the Contact page shows us “hello world from sqlserver”.

Tip

Since the Sql Server is hosted outside of Cloud Foundry, you can reference it while debugging. Just add the connection information to the appsettings.json and load it in the program.cs.

{
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "vcap:services" : {
    "user-provided": [
      {
        "name": "mySqlServerService",
        "instance_name": "mySqlServerService",
        "binding_name": null,
        "credentials": {
          "connectionstring": "Server=tcp:cfnorthwind.database.windows.net,1433;Initial Catalog=Northwind;Persist Security Info=False;User ID=eric@cfnorthwind;Password=4Pjby8$wTk;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;"
        },
        "syslog_drain_url": "",
        "volume_mounts": [],
        "label": "user-provided",
        "tags": []
      }
    ]
  }
}

public static IWebHost BuildWebHost(string[] args) =>
  WebHost.CreateDefaultBuilder(args)
         .ConfigureAppConfiguration((builderContext, configBuilder) =>
         {
            // will be overwritten in Cloud Foundry
            configBuilder.AddJsonFile("appsettings.json");
         })
         .AddCloudFoundry()
         .UseStartup<Startup>()
         .Build();

References

https://docs.cloudfoundry.org/devguide/services/user-provided.html
https://github.com/SteeltoeOSS/Configuration/issues/40

Posted in Development | Tagged , , , | Leave a comment

Add MySql to dotnet core app in Cloud Foundry

In this post you’ll add MySql from the marketplace to a dotnet core mvc app. Mysql was added to the marketplace in this post.

Service

We could use the cli to add MySql and then hook it up to the core app. But since we’ve installed Stratos, we can do this with a wizard:

  1. Select Service: choose p-mysql
  2. Select Plan: choose 10mb (or whatever applies to your needs)
  3. Binding Params (Optional): leave empty
  4. Service Instance:
    • Create and Bind to a new Service Instance
    • Name: mydatastore

You can wait for the changes to be applied or move to Code Changes below.

Code changes

We’re going to edit the dotnet core app.

First add some nugets:

dotnet add package Steeltoe.CloudFoundry.ConnectorCore
dotnet add package Steeltoe.Extensions.Configuration.CloudFoundryCore
dotnet add package MySql.Data
dotnet restore

Then make the changes below.

In the program.cs we need to load the environment variable VCAP_SERVICES and parse it into the configuration. For this we’ll use the Steeltoe extension:

using Steeltoe.Extensions.Configuration.CloudFoundry;

public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.AddCloudFoundry()
.UseStartup<Startup>()
.Build();

Then we need to create a MySqlConnection and inject it into the IoC container. Again with a Steeltoe extension:

using Steeltoe.CloudFoundry.Connector.MySql;

public void ConfigureServices(IServiceCollection services)
{
   services.AddMvc();
   // get the connection to the mysql service
   services.AddMySqlConnection(Configuration);
}

We plan to connect to MySql on the About page. The code below runs a query that returns some text (no mysql objects needed) but only when the connection succeeds.

using MySql.Data.MySqlClient;

public IActionResult About([FromServices] MySqlConnection dbConnection)
{
   var cmd = new MySqlCommand("SELECT \"hello world from mysql \"; ", dbConnection);
   dbConnection.Open();
   ViewData["Message"] = "Your application description page. " + cmd.ExecuteScalar().ToString() ;
   dbConnection.Close();
   return View();
}

The code changes are done. Now cf push the application.

Security

After the cf push completes the application throws an exception:

fail: Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware[0]
An unhandled exception has occurred: Unable to connect to any of the specified MySQL hosts.
MySql.Data.MySqlClient.MySqlException (0x80004005): Unable to connect to any of the specified MySQL hosts. 
---> System.AggregateException: One or more errors occurred. (Connection refused 10.244.0.145:3306) 
---> System.Net.Internals.SocketExceptionFactory+ExtendedSocketException: Connection refused 10.244.0.145:3306

This means the security is not setup for the app to communicate with the MySql endpoint. With a json file we allow communication from our app to the MySql machine over port 3306.

[
   {
      "protocol": "tcp",
      "destination": "10.244.0.145",
      "ports": "3306",
      "log": true,
      "description": "Allow traffic to mysql"
    }
  ]

With the cf statements below we install the security profile in the demo organisation, dev space.

cf create-security-group mysql mysql-asg.json
cf bind-security-group mysql demo dev
cf restart core

After the app is restarted the about page shows us “hello from mysql”.

References

https://github.com/amithn/cloudfoundry-steeltoe-mysql-app
https://steeltoe.io/docs/steeltoe-configuration/#1-2-usage

Posted in Development | Tagged , , | Leave a comment

MySql in marketplace of your Cloud Foundry

This post is a combination of information available elsewhere (links are included) and can be used to get mysql in the marketplace on your local Cloud Foundry.

Tip! Run startupcf.sh from my quickly set environment for local cloud foundry post.

MySql

Follow http://operator-workshop.cloudfoundry.org/labs/services. But first peek below 😉

git clone https://github.com/cloudfoundry/cf-mysql-release.git ~/workspace/cf-mysql-release
cd ~/workspace/cf-mysql-release
git checkout tags/v36.10.0
./scripts/update
bosh create-release
bosh upload-release

git clone https://github.com/EngineerBetter/cf-mysql-deployment.git ~/workspace/cf-mysql-deployment
cd ~/workspace/cf-mysql-deployment

# edit operations/register-proxy-route.yml manually
# edit cloud-config manually

bosh -d cf-mysql deploy \
  cf-mysql-deployment.yml --vars-store mysql-creds.yml \
  -o ./operations/add-broker.yml \
  --vars-file bosh-lite/default-vars.yml \
  --var cf_mysql_external_host=p-mysql.$SYSTEM_DOMAIN \
  --var cf_mysql_host=$BOSH_ENVIRONMENT \
  --var cf_admin_password=$CF_ADMIN_PASSWORD \
  --var cf_api_url=https://api.$SYSTEM_DOMAIN \
  --var cf_skip_ssl_validation=true

I ran into some trouble with the deployment. The url in the register-proxy-route.yml was not working; so I downloaded the file and changed the url in register-proxy-route.yml to my local copy.

In the lab you must find out how to edit the cloud-config. Here’s our take:

# download the cloud-config to a local file
bosh cloud-config > cloud.yml
# edit the local file with vs code
# add massive to vm_types (see cloud.yml below)
code cloud.yml
# upload the cloud-config
bosh update-cloud-config cloud.yml
...
vm_types:
- name: minimal
- name: small
- name: small-highmem
- name: default
- name: massive

Cloud Foundry

After deployment of MySql to Bosh you’ll need to register it in Cloud Foundry. It is in the lab, but we’ve added it for completeness.

bosh deployments
bosh errands -d cf-mysql
bosh run-errand -d cf-mysql broker-registrar 

Now you’ll have MySql in the Marketplace

Posted in Development, Tooling | Tagged , | Leave a comment

Quickly set environment for local Cloud Foundry

We’ve been playing with our local Cloud Foundry installation.

After “save state” and system shutdown some settings are lost. To get our environment quickly setup for local Cloud Foundry we run a script:

source ~/startcf.sh

The contents of the script file is based on the posts on my blog. This sets up the bosh and cf command.

export BOSH_CLIENT=admin
export BOSH_CLIENT_SECRET=`bosh int ~/deployments/vbox/creds.yml --path /admin_password`
export BOSH_ENVIRONMENT=192.168.50.6
export CF_ADMIN_PASSWORD=`bosh interpolate --path /cf_admin_password ~/workspace/cf-deployment/deployment-vars.yml`
export SYSTEM_DOMAIN=bosh-lite.com

sudo route add -net 10.244.0.0/16     192.168.50.6 # Mac OS X

It’s the first command we run in a new terminal window.

Posted in Development | Tagged | Leave a comment