DevOps and Infrastructure Automation on Windows and beyond.

04 Apr 2019

Conditionally create CodePipeline Actions based on Cloudformation Conditions

You can accomplish this by conditionally by inserting the AWS::CodePipeline::Pipeline Resource’s Action into the Actions list using the Fn::If Intrinsic Function referencing your Conditions element, returning the Action when the Condition is true and AWS::NoValue (which removes the property, in this case removing the item from the list) when it is not true.

For example we can cause particular element to be included when the stack is created based on a parameter.

In this case, lets look at deploying a redis cluster Cloudformation file when the pipeline is ran.

We add the parameter and give it some allowed values.

    Type: String
    Description: Do you want to create a redis? (yes/no)
    Default: "no"
    AllowedValues: ["yes", "no"]

Then setup a conditional based on it:

  NeedsRedis: !Equals [ !Ref CreateRedis, "yes" ]

Then in the Actions Section of the CodePipeline resource we can toggle a sections inclusion based on the state of the condition:

- !If 
- NeedsRedis
- Name: !Sub "${ApplicationName}-redis"
  RunOrder: 2
    - Name: Build
    Category: Deploy
    Owner: AWS
    Version: '1'
    Provider: CloudFormation
    RoleArn: !Sub "${CodePipelineCloudFormationRole.Arn}"
    Capabilities: CAPABILITY_NAMED_IAM
    StackName: !Sub "${ApplicationName}-redis"
    TemplatePath: Build::cloudformation/redis.cform
    ParameterOverrides: !Sub |
        "ApplicationName": "${ApplicationName}"
- !Ref AWS::NoValue

12 Jan 2019

Event-stream incident and the need for DevSecOps

Depending on how your build processes work for your in-house applications, if you are using open source frameworks and libraries your dependency tree even for relatively simple applications can depend on a tremendous amount of outside code. For example even relatively simple Ruby on Rails applications pull in a tremendous amount of code and dependencies. The Ruby on Rails project itself at the time of this writing has well over 250 outside dependencies.

This complex web of dependencies means that any one piece of software has hundreds of opportunities for a malicious action to attack users of various frameworks and open source projects by embedding malicious code in a single library, then watch it be pulled into the project or projects he’s targeting and potentially into the code of a specific company. The event stream incident just before the holiday season provides a clear example of this type of attack.

29 Jan 2018

Using Ansible to install a Chocolatey Package Repository

When many Windows administrators think of installing applications even very basic ones it's always... Next Next Next Finish.   Ansible and configuration management tools like it don't work like this, they can't press Next.   They require silent installers that run start to finish on their own.   My recommendation for solving this problem on Windows is Chocolatey.   It brings to Windows all the advantages of a Linux package manager like yum or apt-get and integrates well with Ansible through its win_chocolatey module that we used previously when setting up our test environment.   Since Chocolatey is built on top of the NuGet infrastructure, that means we can install packages from,,, file shares, directories, custom feeds and from private feeds. In this guide, we'll be developing an Ansible role to install internal server we can use to deploy our own company-specific packages.

18 Jan 2018

Fixing Windows Subsystem for Linux (WSL) name resolution errors with VPN

If you've used WSL on a system that connects to a corporate environment you may have experienced issues resolving host names, particularly for your internal network.   Here's how to resolve that.  The primary issue is the interaction between the DNS changes the VPN connection creates (switching to corporate internal DNS) and how WSL discovers DNS settings to populate /etc/resolv.conf is flawed, this is how I fixed it for my corporate VPN solution (GlobalProtect).