<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:foaf="http://xmlns.com/foaf/0.1/" xmlns:og="http://ogp.me/ns#" xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" xmlns:schema="http://schema.org/" xmlns:sioc="http://rdfs.org/sioc/ns#" xmlns:sioct="http://rdfs.org/sioc/types#" xmlns:skos="http://www.w3.org/2004/02/skos/core#" xmlns:xsd="http://www.w3.org/2001/XMLSchema#" version="2.0" xml:base="http://badzilla.co.uk/">
  <channel>
    <title>Docker</title>
    <link>http://badzilla.co.uk/</link>
    <description/>
    <language>en</language>
    
    <item>
  <title>AWS Fargate Static Analysis with PHP</title>
  <link>http://badzilla.co.uk/aws-fargate-static-analysis-php</link>
  <description>
&lt;span&gt;AWS Fargate Static Analysis with PHP&lt;/span&gt;

&lt;span&gt;&lt;span lang="" about="http://badzilla.co.uk/user/1" typeof="schema:Person" property="schema:name" datatype="" xml:lang=""&gt;nigel&lt;/span&gt;&lt;/span&gt;

&lt;span&gt;Mon, 13/01/2020 - 14:28&lt;/span&gt;

      &lt;div class="field field--name-field-heading-image-text field--type-entity-reference-revisions field--label-hidden field--items"&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;&lt;p&gt;In my earlier blog on &lt;a href="http://badzilla.co.uk/aws-fargate-automated-testing-cucumber-gherkin-java-maven-selenium-grid-hub-and-chrome-and-firefox"&gt;AWS Fargate Automated Testing&lt;/a&gt; I spoke about creating an AWS Fargate task definition which would include a web app's codebase and the Cucumber / Gherkin / maven / Java runtime stack. This tutorial is an opportunity to look at the static analysis stage of the pipeline where code is inspected for vulnerabilities, coding standards, compilation errors, copy and paste detection amongst others. Since my background is in Drupal and PHP, my tests will be focused around the PHP language and will use the excellent &lt;a href="https://github.com/jakzal/phpqa"&gt;Static Analysis Tools for PHP repo&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Looking at the jakzal/phpqa repo, it is clear there is a great deal of tooling available. The purpose of this tutorial is take a small sample of these tools and create a Fargate task to run them against my codebase. My somewhat arbitrary selection is:&lt;/p&gt;

&lt;ul&gt;
	&lt;li&gt;phpcpd - Copy/paste detection&lt;/li&gt;
	&lt;li&gt;phpcs - Codesniffer that detects coding standards violations&lt;/li&gt;
	&lt;li&gt;phplint - PHP syntax error checker. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ok - let's get started. &lt;/p&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Create the Dockerfile and the Entrypoint&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;As I have previously mentioned, Fargate is a black box and it doesn't lend itself to command line invocation of the tooling. Typically locally on a laptop we would run the jakzal/phpqa Docker image like: 
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;$  docker run &lt;span style="color: #660033;"&gt;-it&lt;/span&gt; &lt;span style="color: #660033;"&gt;--rm&lt;/span&gt; &lt;span style="color: #660033;"&gt;-v&lt;/span&gt; $&lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;PWD&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;:&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;project &lt;span style="color: #660033;"&gt;-w&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;project  jakzal&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;phpqa phpcpd web&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;core&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;modules&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;views&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;src
$  docker run &lt;span style="color: #660033;"&gt;-it&lt;/span&gt; &lt;span style="color: #660033;"&gt;--rm&lt;/span&gt; &lt;span style="color: #660033;"&gt;-v&lt;/span&gt; $&lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;PWD&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;:&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;project &lt;span style="color: #660033;"&gt;-w&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;project  jakzal&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;phpqa phpcs web&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;core&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;modules&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;views&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;src
$  docker run &lt;span style="color: #660033;"&gt;-it&lt;/span&gt; &lt;span style="color: #660033;"&gt;--rm&lt;/span&gt; &lt;span style="color: #660033;"&gt;-v&lt;/span&gt; $&lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;PWD&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;:&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;project &lt;span style="color: #660033;"&gt;-w&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;project  jakzal&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;phpqa phplint web&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;core&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;modules&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;views&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;src&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
This could obviously be placed in a shell script. Now in Fargate we don't have access to the command line and we have to create a Fargate definition up front before that can be provisioned and then run. So it's a little bit more involved. &lt;br /&gt;&lt;br /&gt;
The simplest approach is to create a Dockerfile based on the jakzal/phpqa repo, and an extrypoint script that will run each one of the tools I have identified. &lt;br /&gt;&lt;br /&gt;The Dockerfile is defined below. Note that I have selected PHP version 7.2. This is the closest supported version of PHP to what I'm running on my production box. Think I need to upgrade that at some point..
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;FROM jakzal&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;phpqa:1.28.1-php7.2
ADD entry.sh &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;entry.sh
RUN &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;bin&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;bash&lt;/span&gt; &lt;span style="color: #660033;"&gt;-c&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;'chmod +x /entry.sh'&lt;/span&gt;
ENTRYPOINT &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #ff0000;"&gt;"/entry.sh"&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
Next up is the entry.sh file. First thing to note is I have added the &lt;strong&gt;set +e&lt;/strong&gt; flag, which is default anyway. This is included to ensure that even if I get some pernickety error messages the script won't terminate immediately, and it acts as an aide memoire that we don't want error termination so don't accidentally copy paste in a competing &lt;strong&gt;set -e&lt;/strong&gt; flag. &lt;br /&gt;&lt;br /&gt;There is then a check whether the shared ECS volume has been loaded - this is the responsibility of the codebase container, but because containers can start at varying times, I have to ensure I don't run the PHP analysis before the volume is ready. &lt;br /&gt;&lt;br /&gt;The path to the source code to perform the analysis on is defined as /var/static_tests/web/core/modules/views/src. This has two components. The first part /var/static_tests/ is the mount point which will correspond to my codebase top level directory. The second component, web/core/modules/views/src points to the core contributed Drupal Views module. This is purely there as a reference to some arbitrary code. I am using the codebase to my own Badzilla which is a site build with no custom code and thus I have none of my own code to use in this sample. 
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #666666; font-style: italic;"&gt;#!/usr/bin/env sh&lt;/span&gt;
 
&lt;span style="color: #000000; font-weight: bold;"&gt;set&lt;/span&gt; +e
 
&lt;span style="color: #000000; font-weight: bold;"&gt;while&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;!&lt;/span&gt; &lt;span style="color: #660033;"&gt;-d&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;var&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;static_tests&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;web &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;do&lt;/span&gt;
  &lt;span style="color: #c20cb9; font-weight: bold;"&gt;sleep&lt;/span&gt; &lt;span style="color: #000000;"&gt;5&lt;/span&gt;
  &lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"Waiting for volume to be mounted and files copied into position"&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;done&lt;/span&gt;
 
phpcpd &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;var&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;static_tests&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;web&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;core&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;modules&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;views&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;src
phpcs &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;var&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;static_tests&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;web&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;core&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;modules&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;views&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;src
phplint &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;var&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;static_tests&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;web&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;core&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;modules&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;views&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;src&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Building the Docker image locally&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;It isn't mandatory to test everything works before constructing the Fargate task definition, but it makes sense to me to test my work locally first. If the Fargate task subsequently fails then I know the problem area will be localised to the AWS eco-system, and probably to Fargate. So I always build locally and run locally first. To build I cd into my Dockerfile / entry.sh entry and issue:
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #666666;"&gt;$ &lt;/span&gt;docker build &lt;span style="color: #660033;"&gt;-f&lt;/span&gt; Dockerfile &lt;span style="color: #660033;"&gt;-t&lt;/span&gt; static-fargate  .&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
To run it's 
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #666666;"&gt;$ &lt;/span&gt;docker run &lt;span style="color: #660033;"&gt;-it&lt;/span&gt; &lt;span style="color: #660033;"&gt;--rm&lt;/span&gt; &lt;span style="color: #660033;"&gt;-v&lt;/span&gt; $&lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;PWD&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;:&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;var&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;static_tests  static-fargate &lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
You can see above I am establishing the Docker volume which will be shared with my codebase.&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;&lt;p&gt;The Docker Hub repo for this is at &lt;a href="https://hub.docker.com/repository/docker/sanddevil/static-fargate"&gt;https://hub.docker.com/repository/docker/sanddevil/static-fargate&lt;/a&gt; and the GitHub repo for the code is at &lt;a href="https://github.com/sanddevil/devops-static-php"&gt;https://github.com/sanddevil/devops-static-php&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Define the Fargate task&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;With everything working locally it's time to build the Fargate task. This is very similar to the script I created in my earlier automated testing blog. There are a few differences obviously. My container stack comprises of a combined PHP + Apache + my own codebase image, and the PHP static analysis  jakzal/phpqa obviously. I use the shell script heredoc convention to define each container. You should note I have now expanded my codebase container to include two shared volumes - one for the automated tests (not discussed here but discussed previously) and the static tests. 
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #666666; font-style: italic;"&gt;#!/bin/bash&lt;/span&gt;
 
 
&lt;span style="color: #007800;"&gt;BRANCH&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;"master"&lt;/span&gt;
&lt;span style="color: #007800;"&gt;REPO&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;"php7.0-apache/&lt;span style="color: #007800;"&gt;${BRANCH}&lt;/span&gt;"&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Repo account and repo&lt;/span&gt;
&lt;span style="color: #007800;"&gt;ECR_ACCOUNT&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;"xxxxxxxxxxx.dkr.ecr.eu-west-2.amazonaws.com"&lt;/span&gt;
&lt;span style="color: #007800;"&gt;ECR_REPO&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${ECR_ACCOUNT}&lt;/span&gt;/&lt;span style="color: #007800;"&gt;${REPO,,}&lt;/span&gt;"&lt;/span&gt;
&lt;span style="color: #007800;"&gt;ECS_CLUSTER&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;"FargatePrototype"&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Get the Task Role ARN for executing the task&lt;/span&gt;
&lt;span style="color: #007800;"&gt;TASK_ARN&lt;/span&gt;=&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;aws iam get-role &lt;span style="color: #660033;"&gt;--role-name&lt;/span&gt; ecsTaskExecutionRole &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; jq .Role.Arn -r&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;
 
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Execution ARN appears to be the same as the Task ARN&lt;/span&gt;
&lt;span style="color: #007800;"&gt;EXECUTION_ARN&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${TASK_ARN}&lt;/span&gt;"&lt;/span&gt;
 
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Determine if the log group already exists: NOTE: "aws ecs register-task-definition" will not create the log group for you!&lt;/span&gt;
&lt;span style="color: #007800;"&gt;LOG_EXISTS&lt;/span&gt;=&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;aws logs describe-log-groups &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; jq &lt;span style="color: #ff0000;"&gt;".logGroups[] | select(.logGroupName == &lt;span style="color: #000099; font-weight: bold;"&gt;\"&lt;/span&gt;/ecs/"&lt;/span&gt;&lt;span style="color: #800000;"&gt;${BRANCH}&lt;/span&gt;&lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #000099; font-weight: bold;"&gt;\"&lt;/span&gt;) | .logGroupName"&lt;/span&gt; &lt;span style="color: #660033;"&gt;-r&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;wc&lt;/span&gt; -l&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${LOG_EXISTS}&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #660033;"&gt;-eq&lt;/span&gt; &lt;span style="color: #000000;"&gt;0&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
	aws logs create-log-group &lt;span style="color: #660033;"&gt;--log-group-name&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"/ecs/&lt;span style="color: #007800;"&gt;${BRANCH}&lt;/span&gt;"&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;
 
&lt;span style="color: #007800;"&gt;CONTAINER_CODEBASE&lt;/span&gt;=$&lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;cat&lt;/span&gt; &lt;span style="color: #cc0000; font-style: italic;"&gt;&lt;&lt;EOF
	{
		"dnsSearchDomains": [],
		"logConfiguration": {
			"logDriver": "awslogs",
			"options": {
				"awslogs-group": "/ecs/${BRANCH}",
				"awslogs-region": "eu-west-2",
				"awslogs-stream-prefix": "ecs"
			}
		},
		"entryPoint": [
			"/usr/local/bin/entry.sh"
		],
		"portMappings": [{
			"hostPort": 80,
			"protocol": "tcp",
			"containerPort": 80
		}],
		"command": [],
		"cpu": 0,
		"image": "${ECR_REPO}",
		"name": "PHPApacheCodebase",
		"mountPoints": [{
			"sourceVolume": "automated_tests",
			"containerPath": "/var/automated_tests",
			"readOnly": false
		},{
			"sourceVolume": "static_tests",
			"containerPath": "/var/static_tests",
			"readOnly": false
		}]
	}
EOF&lt;/span&gt;
&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;
 
&lt;span style="color: #007800;"&gt;CONTAINER_STATIC_PHP&lt;/span&gt;=$&lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;cat&lt;/span&gt; &lt;span style="color: #cc0000; font-style: italic;"&gt;&lt;&lt;EOF
	{
		"dnsSearchDomains": [],
		"logConfiguration": {
			"logDriver": "awslogs",
			"options": {
				"awslogs-group": "/ecs/${BRANCH}",
				"awslogs-region": "eu-west-2",
				"awslogs-stream-prefix": "ecs"
			}
		},
		"entryPoint": [],
		"portMappings": [],
		"command": [],
		"cpu": 0,
		"image": "registry.hub.docker.com/sanddevil/static-fargate",
		"name": "StaticPHP",
		"essential": true,
		"mountPoints": [{
			"sourceVolume": "static_tests",
			"containerPath": "/var/static_tests"
		}]
	}
EOF&lt;/span&gt;
&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;
 
 
&lt;span style="color: #007800;"&gt;CONTAINERS_STATIC&lt;/span&gt;=$&lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;cat&lt;/span&gt; &lt;span style="color: #cc0000; font-style: italic;"&gt;&lt;&lt;EOF
[
${CONTAINER_CODEBASE},
${CONTAINER_STATIC_PHP}
]
EOF&lt;/span&gt;
&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;
 
 
aws ecs register-task-definition \
  &lt;span style="color: #660033;"&gt;--family&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"STATIC-&lt;span style="color: #007800;"&gt;${BRANCH}&lt;/span&gt;"&lt;/span&gt; \
  &lt;span style="color: #660033;"&gt;--volumes&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"name=static_tests,host={}"&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"name=automated_tests,host={}"&lt;/span&gt; \
  &lt;span style="color: #660033;"&gt;--task-role-arn&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$TASK_ARN&lt;/span&gt;"&lt;/span&gt; \
  &lt;span style="color: #660033;"&gt;--execution-role-arn&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${EXECUTION_ARN}&lt;/span&gt;"&lt;/span&gt; \
  &lt;span style="color: #660033;"&gt;--network-mode&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"awsvpc"&lt;/span&gt; \
  &lt;span style="color: #660033;"&gt;--container-definitions&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${CONTAINERS_STATIC}&lt;/span&gt;"&lt;/span&gt; \
  &lt;span style="color: #660033;"&gt;--cpu&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"256"&lt;/span&gt; \
  &lt;span style="color: #660033;"&gt;--memory&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"512"&lt;/span&gt; \
  &lt;span style="color: #660033;"&gt;--requires-compatibilities&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"FARGATE"&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
I'm not quite done yet though. Somehow I need to copy my codebase into the shared Docker volume so that the PHP static analysis container can see it. This is done in the entry.sh script of my PHP + Apache + Codebase image (not discussed here) but the entry.sh file is shown below for completeness. 
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #666666; font-style: italic;"&gt;#!/bin/bash&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;set&lt;/span&gt; &lt;span style="color: #660033;"&gt;-e&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Copy the automated tests into a shared area accessible to maven&lt;/span&gt;
&lt;span style="color: #c20cb9; font-weight: bold;"&gt;cp&lt;/span&gt; &lt;span style="color: #660033;"&gt;-R&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;var&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;www&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;html&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;test&lt;/span&gt;  &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;var&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;automated_tests&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;.
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Copy the PHP codebase into a shared area accessible to the PHP static analysis container&lt;/span&gt;
&lt;span style="color: #c20cb9; font-weight: bold;"&gt;cp&lt;/span&gt; &lt;span style="color: #660033;"&gt;-R&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;var&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;www&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;html&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;web  &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;var&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;static_tests&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;.
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Run Apache in the foreground to prevent the container from quitting&lt;/span&gt;
apache2-foreground&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
Here you can see the copying I do for both the automated tests and the static analysis.&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Running the Fargate task&lt;/div&gt;
      
      &lt;div class="field field--name-field-blog-image field--type-image field--label-hidden field--items"&gt;
              &lt;div class="field--item"&gt;    &lt;img srcset="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2020-01/Screenshot_2020-01-14_at_14_54_17-edited.png?itok=SEUKoW46 325w, https://assets.badzilla.co.uk/s3fs-public/styles/max_650x650/public/2020-01/Screenshot_2020-01-14_at_14_54_17-edited.png?itok=H29PqVpt 650w, https://assets.badzilla.co.uk/s3fs-public/styles/max_1300x1300/public/2020-01/Screenshot_2020-01-14_at_14_54_17-edited.png?itok=vDraWtWi 1300w, https://assets.badzilla.co.uk/s3fs-public/styles/max_2600x2600/public/2020-01/Screenshot_2020-01-14_at_14_54_17-edited.png?itok=9FcxZ4b4 2600w" sizes="(min-width: 1290px) 1290px, 100vw" src="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2020-01/Screenshot_2020-01-14_at_14_54_17-edited.png?itok=SEUKoW46" alt="Task Running" typeof="foaf:Image" class="img-responsive" /&gt;


&lt;/div&gt;
              &lt;div class="field--item"&gt;    &lt;img srcset="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2020-01/Screenshot_2020-01-14_at_14_54_37-edited.png?itok=dd27IZ5a 325w, https://assets.badzilla.co.uk/s3fs-public/styles/max_650x650/public/2020-01/Screenshot_2020-01-14_at_14_54_37-edited.png?itok=pt6QQe2a 650w, https://assets.badzilla.co.uk/s3fs-public/styles/max_1300x1300/public/2020-01/Screenshot_2020-01-14_at_14_54_37-edited.png?itok=sCz9YTr5 1300w, https://assets.badzilla.co.uk/s3fs-public/styles/max_2600x2600/public/2020-01/Screenshot_2020-01-14_at_14_54_37-edited.png?itok=eTY4vp7U 2600w" sizes="(min-width: 1290px) 1290px, 100vw" src="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2020-01/Screenshot_2020-01-14_at_14_54_37-edited.png?itok=dd27IZ5a" alt="CloudWatch Logs" typeof="foaf:Image" class="img-responsive" /&gt;


&lt;/div&gt;
          &lt;/div&gt;
  
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;&lt;p&gt;Normally I would invoke the Fargate task programmatically using AWS CLI but since that leads to a rather dry image-free blog, I will use the console in this instance. My previous blog shows how to navigate around the ECS dashboard to run the task, then you can see the task running in the first screenshot above. It will only run until the entrypoint script terminates as per the rules on how Docker works, so to capture that scrennshot I had to be quick. The second screenshot shows the CloudWatch logs for the task, and you can see there are a few copy/paste errors detected. &lt;/p&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
          &lt;/div&gt;
  
      &lt;div class="field field--name-field-blog-youtube field--type-entity-reference-revisions field--label-hidden field--items"&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-text-youtube paragraph--view-mode--default"&gt;
          
      &lt;/div&gt;
&lt;/div&gt;
          &lt;/div&gt;
  
  &lt;div class="field field--name-field-blog-terms field--type-entity-reference field--label-inline"&gt;
    &lt;div class="field--label"&gt;blog terms&lt;/div&gt;
          &lt;span class="field__items"&gt;
              &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/devops" hreflang="en"&gt;devops&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/aws" hreflang="en"&gt;AWS&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/awscli" hreflang="en"&gt;AWS CLI&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/ecs" hreflang="en"&gt;ECS&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/docker" hreflang="en"&gt;Docker&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/bash" hreflang="en"&gt;bash&lt;/a&gt;&lt;/span&gt;
              &lt;/span&gt;
      &lt;/div&gt;
</description>
  <pubDate>Mon, 13 Jan 2020 14:28:49 +0000</pubDate>
    <dc:creator>nigel</dc:creator>
    <guid isPermaLink="false">176 at http://badzilla.co.uk</guid>
    </item>
<item>
  <title>AWS Fargate Automated Testing with Cucumber, Gherkin, Java, Maven, Selenium Grid Hub and Chrome and Firefox Nodes</title>
  <link>http://badzilla.co.uk/aws-fargate-automated-testing-cucumber-gherkin-java-maven-selenium-grid-hub-and-chrome-and-firefox</link>
  <description>
&lt;span&gt;AWS Fargate Automated Testing with Cucumber, Gherkin, Java, Maven, Selenium Grid Hub and Chrome and Firefox Nodes&lt;/span&gt;

&lt;span&gt;&lt;span lang="" about="http://badzilla.co.uk/user/1" typeof="schema:Person" property="schema:name" datatype="" xml:lang=""&gt;nigel&lt;/span&gt;&lt;/span&gt;

&lt;span&gt;Mon, 09/12/2019 - 08:37&lt;/span&gt;

      &lt;div class="field field--name-field-heading-image-text field--type-entity-reference-revisions field--label-hidden field--items"&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;&lt;p&gt;Tutorial for creating an automated testing AWS Fargate task that will include Docker containers for a full testing framework:&lt;/p&gt;

&lt;ul&gt;
	&lt;li&gt;Maven for build automation&lt;/li&gt;
	&lt;li&gt;Java Runtime to enable the execution of maven and the junit unit testing framework&lt;/li&gt;
	&lt;li&gt;Java Cucumber - a tool for BDD testing&lt;/li&gt;
	&lt;li&gt;Gherkin to define behaviours in the English language&lt;/li&gt;
	&lt;li&gt;Selenium Hub being the central loading point for the tests&lt;/li&gt;
	&lt;li&gt;Selenium Chrome - one of the nodes&lt;/li&gt;
	&lt;li&gt;Selenium Firefox - a second node&lt;/li&gt;
	&lt;li&gt;Apache / PHP - the web app and web server.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is not a trivial exercise but by the end of the blog I will have a working automated testing environment which can be slotted into a DevOps pipeline. Please note this blog is not a tutorial on how to write Cucumber / Gherkin tests, however I will create a few sample Gherkin behaviours and their respective Java Cucumber stepdefs as a starting point. These can then be expanded out by your QA team. &lt;/p&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Starting Point&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;&lt;p&gt;The starting point will be the simple PHP/Apache web app I put together in my previous blog &lt;a href="http://badzilla.co.uk/programmatically-create-aws-ecr-repository-and-commit-docker-image-ecr"&gt;here&lt;/a&gt; - this is a single url website which merely shows the phpinfo() status page. But it's ideal for our automated testing because our testing framework is plenty complex already, and we can still run a few tests against this simple landing page such as whether the additional PHP extensions I included in the Dockerfile are loaded correctly. &lt;/p&gt;

&lt;p&gt;Now we need to build out our testing tree structure. &lt;/p&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;At a sibling level to the docroot directory I created in the previous blog, create the following:
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;$ &lt;span style="color: #c20cb9; font-weight: bold;"&gt;mkdir&lt;/span&gt; &lt;span style="color: #660033;"&gt;-p&lt;/span&gt; mytests&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;src&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;test&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;java&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;mytests
$ &lt;span style="color: #c20cb9; font-weight: bold;"&gt;mkdir&lt;/span&gt; &lt;span style="color: #660033;"&gt;-p&lt;/span&gt; mytests&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;src&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;test&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;resources&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;mytests&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
Now it's time to create the files I need
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;$ &lt;span style="color: #7a0874; font-weight: bold;"&gt;cd&lt;/span&gt; mytests&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;
$ &lt;span style="color: #c20cb9; font-weight: bold;"&gt;touch&lt;/span&gt; pom.xml
$ &lt;span style="color: #c20cb9; font-weight: bold;"&gt;touch&lt;/span&gt; src&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;test&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;java&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;mytests&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;RunCucumberTest.java
$ &lt;span style="color: #c20cb9; font-weight: bold;"&gt;touch&lt;/span&gt; src&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;test&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;java&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;mytests&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;Stepdefs.java
$ &lt;span style="color: #c20cb9; font-weight: bold;"&gt;touch&lt;/span&gt; src&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;test&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;java&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;mytests&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;SetupTestDriver.java
$ &lt;span style="color: #c20cb9; font-weight: bold;"&gt;touch&lt;/span&gt; src&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;test&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;resources&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;mytests&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;home_page.feature&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
This will create a tree structure like this:
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;$ &lt;span style="color: #c20cb9; font-weight: bold;"&gt;tree&lt;/span&gt;
.
&lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt;-- pom.xml
&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;-- src
    &lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;-- &lt;span style="color: #7a0874; font-weight: bold;"&gt;test&lt;/span&gt;
        &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt;-- &lt;span style="color: #c20cb9; font-weight: bold;"&gt;java&lt;/span&gt;
        &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt;   &lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;-- mytests
        &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt;       &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt;-- RunCucumberTest.java
        &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt;       &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt;-- SetupTestDriver.java
        &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt;       &lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;-- Stepdefs.java
        &lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;-- resources
            &lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;-- mytests
                &lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;-- home_page.feature
 
&lt;span style="color: #000000;"&gt;6&lt;/span&gt; directories, &lt;span style="color: #000000;"&gt;5&lt;/span&gt; files&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
Now we need to flesh out those files we created. Firstly the pom file which contains a list of the project's dependencies. Careful inspection will show you that I used the hellocucumber template as my starting point.&lt;br /&gt;
&lt;strong&gt;pom.xml&lt;/strong&gt;
&lt;div class="geshifilter"&gt;&lt;div class="xml geshifilter-xml" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;?xml&lt;/span&gt; &lt;span style="color: #000066;"&gt;version&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;"1.0"&lt;/span&gt; &lt;span style="color: #000066;"&gt;encoding&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;"UTF-8"&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;?&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;project&lt;/span&gt; &lt;span style="color: #000066;"&gt;xmlns&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;"http://maven.apache.org/POM/4.0.0"&lt;/span&gt;&lt;/span&gt;
&lt;span style="color: #009900;"&gt;         &lt;span style="color: #000066;"&gt;xmlns:xsi&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;"http://www.w3.org/2001/XMLSchema-instance"&lt;/span&gt;&lt;/span&gt;
&lt;span style="color: #009900;"&gt;         &lt;span style="color: #000066;"&gt;xsi:schemaLocation&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;modelVersion&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;4.0.0&lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;/modelVersion&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
 
    &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;groupId&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;hellocucumber&lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;/groupId&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;artifactId&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;mytests&lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;/artifactId&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;version&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;1.0.0-SNAPSHOT&lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;/version&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;packaging&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;jar&lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;/packaging&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
 
    &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;properties&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;cucumber.version&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;4.2.6&lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;/cucumber.version&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;project.build.sourceEncoding&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;UTF-8&lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;/project.build.sourceEncoding&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;/properties&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
 
    &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;dependencies&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;dependency&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
            &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;groupId&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;io.cucumber&lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;/groupId&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
            &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;artifactId&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;cucumber-java&lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;/artifactId&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
            &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;version&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;${cucumber.version}&lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;/version&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
            &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;scope&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;test&lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;/scope&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;/dependency&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
 
        &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;dependency&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
            &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;groupId&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;io.cucumber&lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;/groupId&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
            &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;artifactId&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;cucumber-junit&lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;/artifactId&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
            &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;version&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;${cucumber.version}&lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;/version&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
            &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;scope&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;test&lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;/scope&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;/dependency&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
 
        &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;dependency&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
            &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;groupId&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;junit&lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;/groupId&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
            &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;artifactId&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;junit&lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;/artifactId&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
            &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;version&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;4.12&lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;/version&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
            &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;scope&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;test&lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;/scope&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;/dependency&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
 
    &lt;span style="color: #808080; font-style: italic;"&gt;&lt;!-- https://mvnrepository.com/artifact/io.github.bonigarcia/webdrivermanager --&gt;&lt;/span&gt;
    &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;dependency&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;groupId&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;io.github.bonigarcia&lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;/groupId&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;artifactId&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;webdrivermanager&lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;/artifactId&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;version&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;3.7.1&lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;/version&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;/dependency&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
 
	&lt;span style="color: #808080; font-style: italic;"&gt;&lt;!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java --&gt;&lt;/span&gt;
	&lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;dependency&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
    		&lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;groupId&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;org.seleniumhq.selenium&lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;/groupId&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
    		&lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;artifactId&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;selenium-java&lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;/artifactId&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
    		&lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;version&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;3.141.59&lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;/version&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;/dependency&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
 
    &lt;span style="color: #808080; font-style: italic;"&gt;&lt;!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-chrome-driver --&gt;&lt;/span&gt;
    &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;dependency&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;groupId&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;org.seleniumhq.selenium&lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;/groupId&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;artifactId&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;selenium-chrome-driver&lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;/artifactId&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;version&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;3.141.59&lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;/version&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;/dependency&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
 
    &lt;span style="color: #808080; font-style: italic;"&gt;&lt;!-- https://mvnrepository.com/artifact/org.apache.maven.plugins/maven-surefire-plugin --&gt;&lt;/span&gt;
    &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;dependency&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;groupId&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;org.apache.maven.plugins&lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;/groupId&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;artifactId&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;maven-surefire-plugin&lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;/artifactId&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;version&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;2.22.2&lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;/version&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;/dependency&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; 
 
    &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;dependency&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;groupId&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;org.slf4j&lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;/groupId&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;artifactId&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;slf4j-api&lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;/artifactId&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;version&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;1.5.6&lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;/version&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;/dependency&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
 
    &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;dependency&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;groupId&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;org.slf4j&lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;/groupId&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;artifactId&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;slf4j-log4j12&lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;/artifactId&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;version&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;1.5.6&lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;/version&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;/dependency&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; 
 
    &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;/dependencies&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
 
    &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;build&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;plugins&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
            &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;plugin&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
                &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;groupId&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;org.apache.maven.plugins&lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;/groupId&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
                &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;artifactId&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;maven-compiler-plugin&lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;/artifactId&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
                &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;version&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;3.7.0&lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;/version&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
                &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;configuration&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
                    &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;encoding&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;UTF-8&lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;/encoding&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
                    &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;source&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;1.8&lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;/source&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
                    &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;target&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;1.8&lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;/target&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
                &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;/configuration&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
            &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;/plugin&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;/plugins&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;/build&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;/project&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;Now my Gherkin tests themselves. These are rather simple - I am checking for whether my GD and Memecached PHP extensions have been loaded, i.e. they are listed on the front page which just shows the entire PHP configuration. Under normal circumstances Gherkin test tend to be GIVEN..WHEN..THEN constructs, but since I am not actually doing anything (e.g. clicking a button to go somewhere) I only need WHEN..THEN&lt;br /&gt;
&lt;strong&gt;home_page.feature&lt;/strong&gt;
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;Feature: Are we on the Home Page?
 
 
  Scenario: On the home page
    When User is on the Home Page
    Then Message Displayed Memcached
 
    When User is on the Home Page
    Then Message Displayed GD&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;Next is the StepDef file where I convert the Gherkin into Cucumber Java containing the actual business logic behind the quasi-English Gherkin. I don't pretend to be an expert Java coder - I have the sum total of about 4 days experience. Therefore my code is probably sub-optimal, but it does the job and an in-house Java professional could whip it into shape. I have defined two browsers - Firefox and Chrome as per our Selenium configuration, although please note there is currently no semblance of parallel running of the tests in here. That again has been left to more talented Java practitioners than myself. &lt;br /&gt;
&lt;strong&gt;StepDefs.java&lt;/strong&gt;
&lt;div class="geshifilter"&gt;&lt;div class="java geshifilter-java" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;package&lt;/span&gt; &lt;span style="color: #006699;"&gt;mytests&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
 
&lt;span style="color: #000000; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #006699;"&gt;base.SetupTestDriver&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
 
&lt;span style="color: #000000; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #006699;"&gt;java.util.concurrent.TimeUnit&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
 
&lt;span style="color: #000000; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #006699;"&gt;org.openqa.selenium.By&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #006699;"&gt;org.openqa.selenium.WebDriver&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #006699;"&gt;org.openqa.selenium.chrome.ChromeDriver&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #006699;"&gt;org.openqa.selenium.firefox.FirefoxDriver&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #006699;"&gt;io.github.bonigarcia.wdm.WebDriverManager&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
 
&lt;span style="color: #000000; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #006699;"&gt;cucumber.api.java.en.Given&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #006699;"&gt;cucumber.api.java.en.Then&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #006699;"&gt;cucumber.api.java.en.When&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
 
&lt;span style="color: #000000; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #006699;"&gt;java.net.MalformedURLException&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
 
&lt;span style="color: #000000; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #006699;"&gt;static&lt;/span&gt; org.&lt;span style="color: #006633;"&gt;junit&lt;/span&gt;.&lt;span style="color: #000000; font-weight: bold;"&gt;Assert&lt;/span&gt;.&lt;span style="color: #339933;"&gt;*;&lt;/span&gt;
 
 
&lt;span style="color: #000000; font-weight: bold;"&gt;public&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;class&lt;/span&gt; Stepdefs &lt;span style="color: #009900;"&gt;{&lt;/span&gt;
 
	&lt;span style="color: #000000; font-weight: bold;"&gt;public&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;static&lt;/span&gt; WebDriver&lt;span style="color: #009900;"&gt;[&lt;/span&gt;&lt;span style="color: #009900;"&gt;]&lt;/span&gt; drivers&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
	&lt;span style="color: #000000; font-weight: bold;"&gt;public&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;static&lt;/span&gt; &lt;a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+string"&gt;&lt;span style="color: #003399;"&gt;String&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;[&lt;/span&gt;&lt;span style="color: #009900;"&gt;]&lt;/span&gt;&lt;span style="color: #009900;"&gt;[&lt;/span&gt;&lt;span style="color: #009900;"&gt;]&lt;/span&gt; browsers&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
 
    @When&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;"User is on the Home Page"&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;
    &lt;span style="color: #000000; font-weight: bold;"&gt;public&lt;/span&gt; &lt;span style="color: #000066; font-weight: bold;"&gt;void&lt;/span&gt; user_is_on_Home_Page&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;throws&lt;/span&gt; &lt;a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+throwable"&gt;&lt;span style="color: #003399;"&gt;Throwable&lt;/span&gt;&lt;/a&gt; &lt;span style="color: #009900;"&gt;{&lt;/span&gt;
       	browsers &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;new&lt;/span&gt; &lt;a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+string"&gt;&lt;span style="color: #003399;"&gt;String&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;[&lt;/span&gt;&lt;span style="color: #009900;"&gt;]&lt;/span&gt;&lt;span style="color: #009900;"&gt;[&lt;/span&gt;&lt;span style="color: #009900;"&gt;]&lt;/span&gt; &lt;span style="color: #009900;"&gt;{&lt;/span&gt;
       		&lt;span style="color: #009900;"&gt;{&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;"linux"&lt;/span&gt;, &lt;span style="color: #0000ff;"&gt;"firefox"&lt;/span&gt;, &lt;span style="color: #0000ff;"&gt;"http://127.0.0.1"&lt;/span&gt;, &lt;span style="color: #0000ff;"&gt;"http://127.0.0.1:4444"&lt;/span&gt;&lt;span style="color: #009900;"&gt;}&lt;/span&gt;,
            &lt;span style="color: #009900;"&gt;{&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;"linux"&lt;/span&gt;, &lt;span style="color: #0000ff;"&gt;"chrome"&lt;/span&gt;, &lt;span style="color: #0000ff;"&gt;"http://127.0.0.1"&lt;/span&gt;, &lt;span style="color: #0000ff;"&gt;"http://127.0.0.1:4444"&lt;/span&gt;&lt;span style="color: #009900;"&gt;}&lt;/span&gt;
        &lt;span style="color: #009900;"&gt;}&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
 
		drivers &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;new&lt;/span&gt; WebDriver&lt;span style="color: #009900;"&gt;[&lt;/span&gt;browsers.&lt;span style="color: #006633;"&gt;length&lt;/span&gt;&lt;span style="color: #009900;"&gt;]&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
        &lt;span style="color: #000000; font-weight: bold;"&gt;for&lt;/span&gt; &lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #000066; font-weight: bold;"&gt;int&lt;/span&gt; i &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #cc66cc;"&gt;0&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt; i &lt;span style="color: #339933;"&gt;&lt;&lt;/span&gt; browsers.&lt;span style="color: #006633;"&gt;length&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt; i&lt;span style="color: #339933;"&gt;++&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt; &lt;span style="color: #009900;"&gt;{&lt;/span&gt;
        	drivers&lt;span style="color: #009900;"&gt;[&lt;/span&gt;i&lt;span style="color: #009900;"&gt;]&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;new&lt;/span&gt; SetupTestDriver&lt;span style="color: #009900;"&gt;(&lt;/span&gt;browsers&lt;span style="color: #009900;"&gt;[&lt;/span&gt;i&lt;span style="color: #009900;"&gt;]&lt;/span&gt;&lt;span style="color: #009900;"&gt;[&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;0&lt;/span&gt;&lt;span style="color: #009900;"&gt;]&lt;/span&gt;, browsers&lt;span style="color: #009900;"&gt;[&lt;/span&gt;i&lt;span style="color: #009900;"&gt;]&lt;/span&gt;&lt;span style="color: #009900;"&gt;[&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;1&lt;/span&gt;&lt;span style="color: #009900;"&gt;]&lt;/span&gt;, browsers&lt;span style="color: #009900;"&gt;[&lt;/span&gt;i&lt;span style="color: #009900;"&gt;]&lt;/span&gt;&lt;span style="color: #009900;"&gt;[&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;2&lt;/span&gt;&lt;span style="color: #009900;"&gt;]&lt;/span&gt;, browsers&lt;span style="color: #009900;"&gt;[&lt;/span&gt;i&lt;span style="color: #009900;"&gt;]&lt;/span&gt;&lt;span style="color: #009900;"&gt;[&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;3&lt;/span&gt;&lt;span style="color: #009900;"&gt;]&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;.&lt;span style="color: #006633;"&gt;getDriver&lt;/span&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
        &lt;span style="color: #009900;"&gt;}&lt;/span&gt;
    &lt;span style="color: #009900;"&gt;}&lt;/span&gt;
 
    @Then&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;"Message Displayed Memcached"&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;
    &lt;span style="color: #000000; font-weight: bold;"&gt;public&lt;/span&gt; &lt;span style="color: #000066; font-weight: bold;"&gt;void&lt;/span&gt; message_displayed_memcached&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;throws&lt;/span&gt; &lt;a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+throwable"&gt;&lt;span style="color: #003399;"&gt;Throwable&lt;/span&gt;&lt;/a&gt; &lt;span style="color: #009900;"&gt;{&lt;/span&gt;
        &lt;span style="color: #000000; font-weight: bold;"&gt;for&lt;/span&gt; &lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #000066; font-weight: bold;"&gt;int&lt;/span&gt; i &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #cc66cc;"&gt;0&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt; i &lt;span style="color: #339933;"&gt;&lt;&lt;/span&gt; drivers.&lt;span style="color: #006633;"&gt;length&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt; i&lt;span style="color: #339933;"&gt;++&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt; &lt;span style="color: #009900;"&gt;{&lt;/span&gt;
        	&lt;a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+boolean"&gt;&lt;span style="color: #003399;"&gt;Boolean&lt;/span&gt;&lt;/a&gt; exists &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #339933;"&gt;!&lt;/span&gt;drivers&lt;span style="color: #009900;"&gt;[&lt;/span&gt;i&lt;span style="color: #009900;"&gt;]&lt;/span&gt;.&lt;span style="color: #006633;"&gt;findElements&lt;/span&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;By.&lt;span style="color: #006633;"&gt;name&lt;/span&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;"module_memcached"&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;.&lt;span style="color: #006633;"&gt;isEmpty&lt;/span&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
        	drivers&lt;span style="color: #009900;"&gt;[&lt;/span&gt;i&lt;span style="color: #009900;"&gt;]&lt;/span&gt;.&lt;span style="color: #006633;"&gt;quit&lt;/span&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
        	assertTrue&lt;span style="color: #009900;"&gt;(&lt;/span&gt;exists&lt;span style="color: #009900;"&gt;)&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
        &lt;span style="color: #009900;"&gt;}&lt;/span&gt;
    &lt;span style="color: #009900;"&gt;}&lt;/span&gt;
 
	@Then&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;"Message Displayed GD"&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;
	&lt;span style="color: #000000; font-weight: bold;"&gt;public&lt;/span&gt; &lt;span style="color: #000066; font-weight: bold;"&gt;void&lt;/span&gt; gd&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;throws&lt;/span&gt; &lt;a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+throwable"&gt;&lt;span style="color: #003399;"&gt;Throwable&lt;/span&gt;&lt;/a&gt; &lt;span style="color: #009900;"&gt;{&lt;/span&gt;
        &lt;span style="color: #000000; font-weight: bold;"&gt;for&lt;/span&gt; &lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #000066; font-weight: bold;"&gt;int&lt;/span&gt; i &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #cc66cc;"&gt;0&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt; i &lt;span style="color: #339933;"&gt;&lt;&lt;/span&gt; drivers.&lt;span style="color: #006633;"&gt;length&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt; i&lt;span style="color: #339933;"&gt;++&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt; &lt;span style="color: #009900;"&gt;{&lt;/span&gt;
			&lt;a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+boolean"&gt;&lt;span style="color: #003399;"&gt;Boolean&lt;/span&gt;&lt;/a&gt; exists &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #339933;"&gt;!&lt;/span&gt;drivers&lt;span style="color: #009900;"&gt;[&lt;/span&gt;i&lt;span style="color: #009900;"&gt;]&lt;/span&gt;.&lt;span style="color: #006633;"&gt;findElements&lt;/span&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;By.&lt;span style="color: #006633;"&gt;name&lt;/span&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;"module_gd"&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;.&lt;span style="color: #006633;"&gt;isEmpty&lt;/span&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
        	drivers&lt;span style="color: #009900;"&gt;[&lt;/span&gt;i&lt;span style="color: #009900;"&gt;]&lt;/span&gt;.&lt;span style="color: #006633;"&gt;quit&lt;/span&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
        	assertTrue&lt;span style="color: #009900;"&gt;(&lt;/span&gt;exists&lt;span style="color: #009900;"&gt;)&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
        &lt;span style="color: #009900;"&gt;}&lt;/span&gt;
	&lt;span style="color: #009900;"&gt;}&lt;/span&gt;
&lt;span style="color: #009900;"&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;The StepDef file doesn't contain any Firefox or Chrome webdriver startup configuration. This has been placed in a separate Java class.&lt;br /&gt;
&lt;strong&gt;SetupTestDriver.java&lt;/strong&gt;
&lt;div class="geshifilter"&gt;&lt;div class="java geshifilter-java" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #666666; font-style: italic;"&gt;// src/main/java/base/SetupTestDriver.java&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;package&lt;/span&gt; &lt;span style="color: #006699;"&gt;base&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
 
&lt;span style="color: #000000; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #006699;"&gt;org.openqa.selenium.Platform&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #006699;"&gt;org.openqa.selenium.WebDriver&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #006699;"&gt;org.openqa.selenium.chrome.ChromeOptions&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #006699;"&gt;org.openqa.selenium.firefox.FirefoxOptions&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #006699;"&gt;org.openqa.selenium.firefox.FirefoxProfile&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #006699;"&gt;org.openqa.selenium.firefox.FirefoxDriverLogLevel&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #006699;"&gt;org.openqa.selenium.remote.RemoteWebDriver&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #006699;"&gt;org.openqa.selenium.Dimension&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
 
&lt;span style="color: #000000; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #006699;"&gt;java.net.MalformedURLException&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #006699;"&gt;java.net.URL&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #006699;"&gt;java.util.concurrent.TimeUnit&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
 
&lt;span style="color: #000000; font-weight: bold;"&gt;public&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;class&lt;/span&gt; SetupTestDriver &lt;span style="color: #009900;"&gt;{&lt;/span&gt;
    &lt;span style="color: #000000; font-weight: bold;"&gt;private&lt;/span&gt; WebDriver driver &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #000066; font-weight: bold;"&gt;null&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
    &lt;span style="color: #000000; font-weight: bold;"&gt;private&lt;/span&gt; &lt;a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+string"&gt;&lt;span style="color: #003399;"&gt;String&lt;/span&gt;&lt;/a&gt; browser &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #000066; font-weight: bold;"&gt;null&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
    &lt;span style="color: #000000; font-weight: bold;"&gt;private&lt;/span&gt; &lt;a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+string"&gt;&lt;span style="color: #003399;"&gt;String&lt;/span&gt;&lt;/a&gt; baseUrl &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #000066; font-weight: bold;"&gt;null&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
    &lt;span style="color: #000000; font-weight: bold;"&gt;private&lt;/span&gt; &lt;a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+string"&gt;&lt;span style="color: #003399;"&gt;String&lt;/span&gt;&lt;/a&gt; os &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #000066; font-weight: bold;"&gt;null&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
    &lt;span style="color: #000000; font-weight: bold;"&gt;private&lt;/span&gt; &lt;a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+string"&gt;&lt;span style="color: #003399;"&gt;String&lt;/span&gt;&lt;/a&gt; node &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #000066; font-weight: bold;"&gt;null&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
 
    &lt;span style="color: #000000; font-weight: bold;"&gt;public&lt;/span&gt; SetupTestDriver&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+string"&gt;&lt;span style="color: #003399;"&gt;String&lt;/span&gt;&lt;/a&gt; os, &lt;a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+string"&gt;&lt;span style="color: #003399;"&gt;String&lt;/span&gt;&lt;/a&gt; browser, &lt;a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+string"&gt;&lt;span style="color: #003399;"&gt;String&lt;/span&gt;&lt;/a&gt; baseUrl, &lt;a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+string"&gt;&lt;span style="color: #003399;"&gt;String&lt;/span&gt;&lt;/a&gt; node&lt;span style="color: #009900;"&gt;)&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;throws&lt;/span&gt; &lt;a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+malformedurlexception"&gt;&lt;span style="color: #003399;"&gt;MalformedURLException&lt;/span&gt;&lt;/a&gt; &lt;span style="color: #009900;"&gt;{&lt;/span&gt;
        &lt;span style="color: #000000; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #006633;"&gt;browser&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; browser&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
        &lt;span style="color: #000000; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #006633;"&gt;os&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; os&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
        &lt;span style="color: #000000; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #006633;"&gt;baseUrl&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; baseUrl&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
        &lt;span style="color: #000000; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #006633;"&gt;node&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; node&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
 
        Platform platform &lt;span style="color: #339933;"&gt;=&lt;/span&gt; Platform.&lt;span style="color: #006633;"&gt;fromString&lt;/span&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;os.&lt;span style="color: #006633;"&gt;toUpperCase&lt;/span&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
        &lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;browser.&lt;span style="color: #006633;"&gt;equalsIgnoreCase&lt;/span&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;"chrome"&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt; &lt;span style="color: #009900;"&gt;{&lt;/span&gt;
            ChromeOptions chromeOptions &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;new&lt;/span&gt; ChromeOptions&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
            chromeOptions.&lt;span style="color: #006633;"&gt;addArguments&lt;/span&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;"--headless"&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
            chromeOptions.&lt;span style="color: #006633;"&gt;setCapability&lt;/span&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;"platform"&lt;/span&gt;, platform&lt;span style="color: #009900;"&gt;)&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
            &lt;span style="color: #000000; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #006633;"&gt;driver&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;new&lt;/span&gt; RemoteWebDriver&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;new&lt;/span&gt; &lt;a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+url"&gt;&lt;span style="color: #003399;"&gt;URL&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;node &lt;span style="color: #339933;"&gt;+&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;"/wd/hub"&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;, chromeOptions&lt;span style="color: #009900;"&gt;)&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
        &lt;span style="color: #009900;"&gt;}&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;else&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #009900;"&gt;(&lt;/span&gt;browser.&lt;span style="color: #006633;"&gt;equalsIgnoreCase&lt;/span&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;"firefox"&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt; &lt;span style="color: #009900;"&gt;{&lt;/span&gt;
            FirefoxOptions firefoxOptions &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;new&lt;/span&gt; FirefoxOptions&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
            firefoxOptions.&lt;span style="color: #006633;"&gt;setProfile&lt;/span&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;new&lt;/span&gt; FirefoxProfile&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
            firefoxOptions.&lt;span style="color: #006633;"&gt;setCapability&lt;/span&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;"platform"&lt;/span&gt;, platform&lt;span style="color: #009900;"&gt;)&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
            firefoxOptions.&lt;span style="color: #006633;"&gt;setHeadless&lt;/span&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #000066; font-weight: bold;"&gt;true&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
            &lt;span style="color: #000000; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #006633;"&gt;driver&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;new&lt;/span&gt; RemoteWebDriver&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;new&lt;/span&gt; &lt;a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+url"&gt;&lt;span style="color: #003399;"&gt;URL&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;node &lt;span style="color: #339933;"&gt;+&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;"/wd/hub"&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;, firefoxOptions&lt;span style="color: #009900;"&gt;)&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
        &lt;span style="color: #009900;"&gt;}&lt;/span&gt;
 
        &lt;span style="color: #000000; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #006633;"&gt;driver&lt;/span&gt;.&lt;span style="color: #006633;"&gt;manage&lt;/span&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;.&lt;span style="color: #006633;"&gt;timeouts&lt;/span&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;.&lt;span style="color: #006633;"&gt;implicitlyWait&lt;/span&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;10&lt;/span&gt;, TimeUnit.&lt;span style="color: #006633;"&gt;SECONDS&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
        &lt;span style="color: #666666; font-style: italic;"&gt;// Maximizing the screen doesn't appear to work.&lt;/span&gt;
        &lt;span style="color: #000000; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #006633;"&gt;driver&lt;/span&gt;.&lt;span style="color: #006633;"&gt;manage&lt;/span&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;.&lt;span style="color: #006633;"&gt;window&lt;/span&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;.&lt;span style="color: #006633;"&gt;setSize&lt;/span&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;new&lt;/span&gt; &lt;a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+dimension"&gt;&lt;span style="color: #003399;"&gt;Dimension&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;1600&lt;/span&gt;,&lt;span style="color: #cc66cc;"&gt;900&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
        &lt;span style="color: #000000; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #006633;"&gt;driver&lt;/span&gt;.&lt;span style="color: #006633;"&gt;get&lt;/span&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;baseUrl&lt;span style="color: #009900;"&gt;)&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
 
    &lt;span style="color: #009900;"&gt;}&lt;/span&gt;
 
    &lt;span style="color: #000000; font-weight: bold;"&gt;public&lt;/span&gt; &lt;a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+string"&gt;&lt;span style="color: #003399;"&gt;String&lt;/span&gt;&lt;/a&gt; getOs&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt; &lt;span style="color: #009900;"&gt;{&lt;/span&gt;
        &lt;span style="color: #000000; font-weight: bold;"&gt;return&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #006633;"&gt;os&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
    &lt;span style="color: #009900;"&gt;}&lt;/span&gt;
 
    &lt;span style="color: #000000; font-weight: bold;"&gt;public&lt;/span&gt; &lt;a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+string"&gt;&lt;span style="color: #003399;"&gt;String&lt;/span&gt;&lt;/a&gt; getBrowser&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt; &lt;span style="color: #009900;"&gt;{&lt;/span&gt;
        &lt;span style="color: #000000; font-weight: bold;"&gt;return&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #006633;"&gt;browser&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
    &lt;span style="color: #009900;"&gt;}&lt;/span&gt;
 
    &lt;span style="color: #000000; font-weight: bold;"&gt;public&lt;/span&gt; &lt;a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+string"&gt;&lt;span style="color: #003399;"&gt;String&lt;/span&gt;&lt;/a&gt; getBaseUrl&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt; &lt;span style="color: #009900;"&gt;{&lt;/span&gt;
        &lt;span style="color: #000000; font-weight: bold;"&gt;return&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #006633;"&gt;baseUrl&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
    &lt;span style="color: #009900;"&gt;}&lt;/span&gt;
 
    &lt;span style="color: #000000; font-weight: bold;"&gt;public&lt;/span&gt; &lt;a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+string"&gt;&lt;span style="color: #003399;"&gt;String&lt;/span&gt;&lt;/a&gt; getNode&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt; &lt;span style="color: #009900;"&gt;{&lt;/span&gt;
        &lt;span style="color: #000000; font-weight: bold;"&gt;return&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #006633;"&gt;node&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
    &lt;span style="color: #009900;"&gt;}&lt;/span&gt;
 
    &lt;span style="color: #000000; font-weight: bold;"&gt;public&lt;/span&gt; WebDriver getDriver&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt; &lt;span style="color: #009900;"&gt;{&lt;/span&gt;
        &lt;span style="color: #000000; font-weight: bold;"&gt;return&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #006633;"&gt;driver&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
    &lt;span style="color: #009900;"&gt;}&lt;/span&gt;
&lt;span style="color: #009900;"&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;Finally there's some code to perform the glue between Gherkin and Cucumber.&lt;br /&gt;
&lt;strong&gt;RunCucumberTest.java&lt;/strong&gt;
&lt;div class="geshifilter"&gt;&lt;div class="java geshifilter-java" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;package&lt;/span&gt; &lt;span style="color: #006699;"&gt;mytests&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
 
&lt;span style="color: #000000; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #006699;"&gt;cucumber.api.CucumberOptions&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #006699;"&gt;cucumber.api.junit.Cucumber&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;import&lt;/span&gt; &lt;span style="color: #006699;"&gt;org.junit.runner.RunWith&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
 
@RunWith&lt;span style="color: #009900;"&gt;(&lt;/span&gt;Cucumber.&lt;span style="color: #000000; font-weight: bold;"&gt;class&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;
@CucumberOptions&lt;span style="color: #009900;"&gt;(&lt;/span&gt;plugin &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #009900;"&gt;{&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;"pretty"&lt;/span&gt;&lt;span style="color: #009900;"&gt;}&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;public&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;class&lt;/span&gt; RunCucumberTest &lt;span style="color: #009900;"&gt;{&lt;/span&gt;
&lt;span style="color: #009900;"&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Build the Docker Codebase + PHP/Apache&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;&lt;p&gt;In my previous blog &lt;a href="http://badzilla.co.uk/programmatically-create-aws-ecr-repository-and-commit-docker-image-ecr"&gt;here&lt;/a&gt; I showed how to add the codebase to the php:7.2-apache image. The codebase has now changed, and I now have two top level sibling directories &lt;em&gt;docroot&lt;/em&gt; and &lt;em&gt;mytests &lt;/em&gt;- which contains the automated test code I've just added. There is a change we need to make to the &lt;em&gt;Dockerfile&lt;/em&gt; in this revision, and the inclusion of an entrypoint script called &lt;em&gt;entry.sh&lt;/em&gt;. The &lt;em&gt;entry.sh &lt;/em&gt;file will copy the test code suite into a shared Fargate non-persistent drive so that the Maven container can access the codebase and run the tests against it. Once the copy of files has been completed, Apache must be run in foreground mode to prevent the container from quitting. Below we have the new version of the &lt;em&gt;Dockerfile&lt;/em&gt;, and the &lt;em&gt;entry.sh&lt;/em&gt; file. The image needs to be rebuilt, but since that was covered in the previous blog, it is omitted here. &lt;/p&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;&lt;strong&gt;Dockerfile&lt;/strong&gt;
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;FROM php:&lt;span style="color: #000000;"&gt;7.2&lt;/span&gt;-apache
RUN &lt;span style="color: #c20cb9; font-weight: bold;"&gt;apt-get update&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;&amp;&amp;&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;apt-get install&lt;/span&gt; &lt;span style="color: #660033;"&gt;-y&lt;/span&gt; libmemcached-dev zlib1g-dev \
    libfreetype6-dev \
    libjpeg62-turbo-dev \
    libpng-dev \
    libwebp-dev \
    &lt;span style="color: #000000; font-weight: bold;"&gt;&amp;&amp;&lt;/span&gt; pecl &lt;span style="color: #c20cb9; font-weight: bold;"&gt;install&lt;/span&gt; memcached \
    &lt;span style="color: #000000; font-weight: bold;"&gt;&amp;&amp;&lt;/span&gt; docker-php-ext-enable memcached \
    &lt;span style="color: #000000; font-weight: bold;"&gt;&amp;&amp;&lt;/span&gt; docker-php-ext-configure gd &lt;span style="color: #660033;"&gt;--with-gd&lt;/span&gt; &lt;span style="color: #660033;"&gt;--with-webp-dir&lt;/span&gt; &lt;span style="color: #660033;"&gt;--with-jpeg-dir&lt;/span&gt; \
       &lt;span style="color: #660033;"&gt;--with-png-dir&lt;/span&gt; &lt;span style="color: #660033;"&gt;--with-zlib-dir&lt;/span&gt; &lt;span style="color: #660033;"&gt;--with-freetype-dir&lt;/span&gt; \
    &lt;span style="color: #000000; font-weight: bold;"&gt;&amp;&amp;&lt;/span&gt; docker-php-ext-install gd
COPY &lt;span style="color: #660033;"&gt;--chown&lt;/span&gt;=www-data:www-data .&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;var&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;www&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;html&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;.
COPY entry.sh &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;usr&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;local&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;bin&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;.
ENV AH_SITE_ENVIRONMENT devops
ENV APACHE_DOCUMENT_ROOT &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;var&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;www&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;html&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;docroot
RUN &lt;span style="color: #c20cb9; font-weight: bold;"&gt;sed&lt;/span&gt; &lt;span style="color: #660033;"&gt;-ri&lt;/span&gt; &lt;span style="color: #660033;"&gt;-e&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;'s!/var/www/html!${APACHE_DOCUMENT_ROOT}!g'&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;etc&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;apache2&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;sites-available&lt;span style="color: #000000; font-weight: bold;"&gt;/*&lt;/span&gt;.conf
RUN &lt;span style="color: #c20cb9; font-weight: bold;"&gt;sed&lt;/span&gt; &lt;span style="color: #660033;"&gt;-ri&lt;/span&gt; &lt;span style="color: #660033;"&gt;-e&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;'s!/var/www/!${APACHE_DOCUMENT_ROOT}!g'&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;etc&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;apache2&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;apache2.conf &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;etc&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;apache2&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;conf-available&lt;span style="color: #000000; font-weight: bold;"&gt;/*&lt;/span&gt;.conf
RUN &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;bin&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;bash&lt;/span&gt; &lt;span style="color: #660033;"&gt;-c&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;'chmod +x /usr/local/bin/entry.sh'&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;strong&gt;entry.sh&lt;/strong&gt;
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #666666; font-style: italic;"&gt;#!/bin/bash&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;set&lt;/span&gt; &lt;span style="color: #660033;"&gt;-e&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Copy the automated tests into a shared areaaccessible to maven&lt;/span&gt;
&lt;span style="color: #c20cb9; font-weight: bold;"&gt;cp&lt;/span&gt; &lt;span style="color: #660033;"&gt;-R&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;var&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;www&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;html&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;mytests  &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;var&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;automated_tests&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;.
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Run Apache in the foreground to prevent the container from quitting&lt;/span&gt;
apache2-foreground&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Maven:3.6.2-jdk-13&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;&lt;p&gt;The Java runtime is bundled with the Maven image if the correct tag is selected. I have opted for maven:3.6.2-jdk-13 which is up to date and supported. This requires a small amount of customisation, so again a Dockerfile will be needed. In this instance I want to put a wait loop in the entrypoint script to ensure that there's no attempt to run the tests before the non-persistent shared drive containing the test suite has been mounted by the d8codebase container. At the end I exec the &lt;em&gt;mvn clean install&lt;/em&gt; command to run the tests. &lt;/p&gt;

&lt;p&gt;The easiest way of achieving this is to edit the &lt;em&gt;mvn-entrypoint.sh &lt;/em&gt;script which is in &lt;em&gt;/usrlocal/bin.&lt;/em&gt; I copied out of the image to edit and the Dockerfile copies it back into place. &lt;/p&gt;

&lt;p&gt;Using my previous blog I built this, tagged and pushed to ECR using the image name &lt;em&gt;d8maven. &lt;/em&gt;The instructions aren't copied here for brevity reasons - please refer to my previous blog if you need to. &lt;/p&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;&lt;strong&gt;Dockerfile&lt;/strong&gt;
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;FROM maven:3.6.2-jdk-&lt;span style="color: #000000;"&gt;13&lt;/span&gt;
COPY mvn-entrypoint.sh &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;usr&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;local&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;bin&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;mvn-entrypoint.sh
RUN &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;bin&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;bash&lt;/span&gt; &lt;span style="color: #660033;"&gt;-c&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;'chmod +x /usr/local/bin/mvn-entrypoint.sh'&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;strong&gt;mvn-entrypoint.sh&lt;/strong&gt;
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #666666; font-style: italic;"&gt;#! /bin/sh -eu&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Copy files from /usr/share/maven/ref into ${MAVEN_CONFIG}&lt;/span&gt;
&lt;span style="color: #666666; font-style: italic;"&gt;# So the initial ~/.m2 is set with expected content.&lt;/span&gt;
&lt;span style="color: #666666; font-style: italic;"&gt;# Don't override, as this is just a reference setup&lt;/span&gt;
 
copy_reference_files&lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;{&lt;/span&gt;
  &lt;span style="color: #7a0874; font-weight: bold;"&gt;local&lt;/span&gt; &lt;span style="color: #007800;"&gt;log&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$MAVEN_CONFIG&lt;/span&gt;/copy_reference_file.log"&lt;/span&gt;
  &lt;span style="color: #7a0874; font-weight: bold;"&gt;local&lt;/span&gt; &lt;span style="color: #007800;"&gt;ref&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;"/usr/share/maven/ref"&lt;/span&gt;
 
  &lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;mkdir&lt;/span&gt; &lt;span style="color: #660033;"&gt;-p&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${MAVEN_CONFIG}&lt;/span&gt;/repository"&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;&amp;&amp;&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;touch&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${log}&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;dev&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;null &lt;span style="color: #000000;"&gt;2&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;1&lt;/span&gt; ; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
      &lt;span style="color: #7a0874; font-weight: bold;"&gt;cd&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${ref}&lt;/span&gt;"&lt;/span&gt;
      &lt;span style="color: #7a0874; font-weight: bold;"&gt;local&lt;/span&gt; &lt;span style="color: #007800;"&gt;reflink&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;""&lt;/span&gt;
      &lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;cp&lt;/span&gt; &lt;span style="color: #660033;"&gt;--help&lt;/span&gt; &lt;span style="color: #000000;"&gt;2&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;1&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;grep&lt;/span&gt; &lt;span style="color: #660033;"&gt;-q&lt;/span&gt; reflink ; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
          &lt;span style="color: #007800;"&gt;reflink&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;"--reflink=auto"&lt;/span&gt;
      &lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;
      &lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #660033;"&gt;-n&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$(find "${MAVEN_CONFIG}/repository" -maxdepth 0 -type d -empty 2&gt;/dev/null)&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt; ; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
          &lt;span style="color: #666666; font-style: italic;"&gt;# destination is empty...&lt;/span&gt;
          &lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"--- Copying all files to &lt;span style="color: #007800;"&gt;${MAVEN_CONFIG}&lt;/span&gt; at &lt;span style="color: #007800;"&gt;$(date)&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&gt;&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${log}&lt;/span&gt;"&lt;/span&gt;
          &lt;span style="color: #c20cb9; font-weight: bold;"&gt;cp&lt;/span&gt; &lt;span style="color: #660033;"&gt;-rv&lt;/span&gt; &lt;span style="color: #800000;"&gt;${reflink}&lt;/span&gt; . &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${MAVEN_CONFIG}&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&gt;&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${log}&lt;/span&gt;"&lt;/span&gt;
      &lt;span style="color: #000000; font-weight: bold;"&gt;else&lt;/span&gt;
          &lt;span style="color: #666666; font-style: italic;"&gt;# destination is non-empty, copy file-by-file&lt;/span&gt;
          &lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"--- Copying individual files to &lt;span style="color: #007800;"&gt;${MAVEN_CONFIG}&lt;/span&gt; at &lt;span style="color: #007800;"&gt;$(date)&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&gt;&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${log}&lt;/span&gt;"&lt;/span&gt;
          &lt;span style="color: #c20cb9; font-weight: bold;"&gt;find&lt;/span&gt; . &lt;span style="color: #660033;"&gt;-type&lt;/span&gt; f &lt;span style="color: #660033;"&gt;-exec&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;sh&lt;/span&gt; &lt;span style="color: #660033;"&gt;-eu&lt;/span&gt; &lt;span style="color: #660033;"&gt;-c&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;'
              log="${1}"
              shift
              reflink="${1}"
              shift
              for f in "$@" ; do
                  if [ ! -e "${MAVEN_CONFIG}/${f}" ] || [ -e "${f}.override" ] ; then
                      mkdir -p "${MAVEN_CONFIG}/$(dirname "${f}")"
                      cp -rv ${reflink} "${f}" "${MAVEN_CONFIG}/${f}" &gt;&gt; "${log}"
                  fi
              done
          '&lt;/span&gt; _ &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${log}&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${reflink}&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;{&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;}&lt;/span&gt; +
      &lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;
      &lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&gt;&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${log}&lt;/span&gt;"&lt;/span&gt;
  &lt;span style="color: #000000; font-weight: bold;"&gt;else&lt;/span&gt;
    &lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"Can not write to &lt;span style="color: #007800;"&gt;${log}&lt;/span&gt;. Wrong volume permissions? Carrying on ..."&lt;/span&gt;
  &lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;
&lt;span style="color: #7a0874; font-weight: bold;"&gt;}&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Wait until we see the test files that are being copied from the PHP/Apache/Codebase container to a shared volume.&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;while&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;!&lt;/span&gt; &lt;span style="color: #660033;"&gt;-d&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;var&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;automated_tests&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;mytests &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;do&lt;/span&gt;
  &lt;span style="color: #c20cb9; font-weight: bold;"&gt;sleep&lt;/span&gt; &lt;span style="color: #000000;"&gt;2&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;done&lt;/span&gt;
 
&lt;span style="color: #007800;"&gt;owd&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$(pwd)&lt;/span&gt;"&lt;/span&gt;
copy_reference_files
&lt;span style="color: #7a0874; font-weight: bold;"&gt;unset&lt;/span&gt; MAVEN_CONFIG
 
&lt;span style="color: #7a0874; font-weight: bold;"&gt;cd&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${owd}&lt;/span&gt;"&lt;/span&gt;
&lt;span style="color: #7a0874; font-weight: bold;"&gt;unset&lt;/span&gt; owd
 
&lt;span style="color: #7a0874; font-weight: bold;"&gt;exec&lt;/span&gt; mvn &lt;span style="color: #660033;"&gt;-f&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;var&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;automated_tests&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;mytests &lt;span style="color: #660033;"&gt;-q&lt;/span&gt; clean &lt;span style="color: #c20cb9; font-weight: bold;"&gt;install&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Define the Fargate Task&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;&lt;p&gt;I now have all parts I need apart from a shell script to actually define the Fargate task which will contain all the config for the containers. I have made extensive use of the heredoc convention in the shell script - one per container definition - which makes it easier to read, and also means when I come to make up other tasks (such as static analysis, and persistent playground) I can simple swap out those containers I don't need.&lt;br /&gt;
&lt;br /&gt;
There are a few comments here to note. &lt;/p&gt;

&lt;ul&gt;
	&lt;li&gt;You cannot create a Fargate Task without the IAM ecsTaskExecutionRole, but that will not be created for you. It is however created when you manually create your first Fargate task in the AWS console. Of course ecsTaskExecutionRole can be created programmatically too - and will be the subject of a block at another time.&lt;/li&gt;
	&lt;li&gt;The Fargate task definition will not create your CloudFront log group for you! Therefore I do a check in the script to see if it already exists, and if not then create.&lt;/li&gt;
	&lt;li&gt;I have defined a mount point to where I copy the test suite. This is because the test suite is in the code repository which is copied into the PHP/Apache container, but is needed by the Maven container also.&lt;/li&gt;
	&lt;li&gt;The Selenium Chrome browser is using a non-standard port 5556. This is because it would clash with Firefox otherwise which also defaults to port 5555. You must remember to use an environmental variable NODE_PORT to change the port as well as the hostPort and containerPort.&lt;/li&gt;
	&lt;li&gt;I have defaulted the task's compute to extremely high cpu and memory. They should be reduced using trial and error to avoid incurring high compute fees.&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #666666; font-style: italic;"&gt;#!/bin/bash&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Rewrite branch name so no feature/ hotfix/ forward slash&lt;/span&gt;
&lt;span style="color: #007800;"&gt;BRANCH&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;"selenium-testing"&lt;/span&gt;
&lt;span style="color: #007800;"&gt;REPO&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;"d8codebase"&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Repo account and repo&lt;/span&gt;
&lt;span style="color: #007800;"&gt;ECR_ACCOUNT&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;"XXXXXXXXXXX.dkr.ecr.eu-west-2.amazonaws.com"&lt;/span&gt;
&lt;span style="color: #007800;"&gt;ECR_REPO&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${ECR_ACCOUNT}&lt;/span&gt;/&lt;span style="color: #007800;"&gt;${REPO,,}&lt;/span&gt;"&lt;/span&gt;
&lt;span style="color: #007800;"&gt;ECS_CLUSTER&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;"default"&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Get the Task Role ARN for executing the task&lt;/span&gt;
&lt;span style="color: #007800;"&gt;TASK_ARN&lt;/span&gt;=&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;aws iam get-role &lt;span style="color: #660033;"&gt;--role-name&lt;/span&gt; ecsTaskExecutionRole &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; jq .Role.Arn -r&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;
 
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Execution ARN appears to be the same as the Task ARN&lt;/span&gt;
&lt;span style="color: #007800;"&gt;EXECUTION_ARN&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${TASK_ARN}&lt;/span&gt;"&lt;/span&gt;
 
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Determine if the log group already exists: NOTE: "aws ecs register-task-definition" will not create the log group for you!&lt;/span&gt;
&lt;span style="color: #007800;"&gt;LOG_EXISTS&lt;/span&gt;=&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;aws logs describe-log-groups &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; jq &lt;span style="color: #ff0000;"&gt;".logGroups[] | select(.logGroupName == &lt;span style="color: #000099; font-weight: bold;"&gt;\"&lt;/span&gt;/ecs/"&lt;/span&gt;&lt;span style="color: #800000;"&gt;${BRANCH}&lt;/span&gt;&lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #000099; font-weight: bold;"&gt;\"&lt;/span&gt;) | .logGroupName"&lt;/span&gt; &lt;span style="color: #660033;"&gt;-r&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;wc&lt;/span&gt; -l&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${LOG_EXISTS}&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #660033;"&gt;-eq&lt;/span&gt; &lt;span style="color: #000000;"&gt;0&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
	aws logs create-log-group &lt;span style="color: #660033;"&gt;--log-group-name&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"/ecs/&lt;span style="color: #007800;"&gt;${BRANCH}&lt;/span&gt;"&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;
 
&lt;span style="color: #007800;"&gt;CONTAINER_CODEBASE&lt;/span&gt;=$&lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;cat&lt;/span&gt; &lt;span style="color: #cc0000; font-style: italic;"&gt;&lt;&lt;EOF
	{
		"dnsSearchDomains": [],
		"logConfiguration": {
			"logDriver": "awslogs",
			"options": {
				"awslogs-group": "/ecs/${BRANCH}",
				"awslogs-region": "eu-west-2",
				"awslogs-stream-prefix": "ecs"
			}
		},
		"entryPoint": [
			"/usr/local/bin/entry.sh"
		],
		"portMappings": [{
			"hostPort": 80,
			"protocol": "tcp",
			"containerPort": 80
		}],
		"command": [],
		"cpu": 0,
		"image": "${ECR_REPO}",
		"name": "d8codebase",
		"mountPoints": [{
			"sourceVolume": "automated_tests",
			"containerPath": "/var/automated_tests",
			"readOnly": false
		}]
	}
EOF&lt;/span&gt;
&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;
 
&lt;span style="color: #007800;"&gt;CONTAINER_SELENIUM_HUB&lt;/span&gt;=$&lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;cat&lt;/span&gt; &lt;span style="color: #cc0000; font-style: italic;"&gt;&lt;&lt;EOF
	{
		"dnsSearchDomains": [],
		"logConfiguration": {
			"logDriver": "awslogs",
			"options": {
				"awslogs-group": "/ecs/${BRANCH}",
				"awslogs-region": "eu-west-2",
				"awslogs-stream-prefix": "ecs"
			}
		},
		"entryPoint": [],
		"portMappings": [{
			"hostPort": 4444,
			"protocol": "tcp",
			"containerPort": 4444
		}],
		"command": [],
		"cpu": 0,
		"environment": [{
			"name": "SE_OPTS","value": "-debug"
		}],
		"image": "registry.hub.docker.com/selenium/hub:3.141.59-uranium",
		"name": "selenium-hub"
	}
EOF&lt;/span&gt;
&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;
 
&lt;span style="color: #007800;"&gt;CONTAINER_SELENIUM_FIREFOX&lt;/span&gt;=$&lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;cat&lt;/span&gt; &lt;span style="color: #cc0000; font-style: italic;"&gt;&lt;&lt;EOF
	{
		"dnsSearchDomains": [],
		"logConfiguration": {
			"logDriver": "awslogs",
			"options": {
				"awslogs-group": "/ecs/${BRANCH}",
				"awslogs-region": "eu-west-2",
				"awslogs-stream-prefix": "ecs"
			}
		},
		"entryPoint": [],
		"portMappings": [{
			"hostPort": 5555,
			"protocol": "tcp",
			"containerPort": 5555
		}],
		"command": [],
		"cpu": 0,
		"environment": [{
			"name": "NODE_MAX_INSTANCES", "value": "5"
		},{
			"name": "NODE_MAX_SESSIONS", "value": "5"
		},{
			"name": "HUB_HOST", "value": "127.0.0.1"
		},{
			"name": "HUB_PORT", "value": "4444"
		}],
		"image": "registry.hub.docker.com/selenium/node-firefox:3.141.59-uranium",
		"name": "SeleniumNodeFirefox"
	}
EOF&lt;/span&gt;
&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;
 
&lt;span style="color: #007800;"&gt;CONTAINER_SELENIUM_CHROME&lt;/span&gt;=$&lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;cat&lt;/span&gt; &lt;span style="color: #cc0000; font-style: italic;"&gt;&lt;&lt;EOF
 	{
 		"dnsSearchDomains": [],
 		"logConfiguration": {
 			"logDriver": "awslogs",
 			"options": {
 				"awslogs-group": "/ecs/${BRANCH}",
 				"awslogs-region": "eu-west-2",
 				"awslogs-stream-prefix": "ecs"
 			}
 		},
 		"entryPoint": [],
 		"portMappings": [{
 			"hostPort": 5556,
 			"protocol": "tcp",
 			"containerPort": 5556
 		}],
 		"command": [],
 		"cpu": 0,
 		"environment": [{
 			"name": "NODE_MAX_INSTANCES", "value": "5"
 		},{
 			"name": "NODE_MAX_SESSIONS", "value": "5"
 		},{
 			"name": "HUB_HOST", "value": "127.0.0.1"
 		},{
 			"name": "HUB_PORT", "value": "4444"
 		},{
 			"name": "NODE_PORT", "value": "5556"
 		}],
 		"image": "registry.hub.docker.com/selenium/node-chrome:3.141.59-uranium",
 		"name": "SeleniumNodeChrome"
 	}
EOF&lt;/span&gt;
&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;
 
&lt;span style="color: #007800;"&gt;CONTAINER_MAVEN&lt;/span&gt;=$&lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;cat&lt;/span&gt; &lt;span style="color: #cc0000; font-style: italic;"&gt;&lt;&lt;EOF
	{
		"dnsSearchDomains": [],
		"logConfiguration": {
			"logDriver": "awslogs",
			"options": {
				"awslogs-group": "/ecs/${BRANCH}",
				"awslogs-region": "eu-west-2",
				"awslogs-stream-prefix": "ecs"
			}
		},
		"entryPoint": [],
		"portMappings": [],
		"command": [],
		"cpu": 0,
		"image": "${ECR_ACCOUNT}/d8maven",
		"name": "Maven",
		"essential": true,
		"mountPoints": [{
			"sourceVolume": "automated_tests",
			"containerPath": "/var/automated_tests"
		}]
	}
EOF&lt;/span&gt;
&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;
 
 
&lt;span style="color: #007800;"&gt;CONTAINERS_AUTOMATIC&lt;/span&gt;=$&lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;cat&lt;/span&gt; &lt;span style="color: #cc0000; font-style: italic;"&gt;&lt;&lt;EOF
[
${CONTAINER_CODEBASE},
${CONTAINER_SELENIUM_HUB},
${CONTAINER_SELENIUM_FIREFOX},
${CONTAINER_MAVEN},
${CONTAINER_SELENIUM_CHROME}
]
EOF&lt;/span&gt;
&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;
 
 
aws ecs register-task-definition \
  &lt;span style="color: #660033;"&gt;--family&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"AUTOMATION-&lt;span style="color: #007800;"&gt;${BRANCH}&lt;/span&gt;"&lt;/span&gt; \
  &lt;span style="color: #660033;"&gt;--volumes&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"name=automated_tests,host={}"&lt;/span&gt; \
  &lt;span style="color: #660033;"&gt;--task-role-arn&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$TASK_ARN&lt;/span&gt;"&lt;/span&gt; \
  &lt;span style="color: #660033;"&gt;--execution-role-arn&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${EXECUTION_ARN}&lt;/span&gt;"&lt;/span&gt; \
  &lt;span style="color: #660033;"&gt;--network-mode&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"awsvpc"&lt;/span&gt; \
  &lt;span style="color: #660033;"&gt;--container-definitions&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${CONTAINERS_AUTOMATIC}&lt;/span&gt;"&lt;/span&gt; \
  &lt;span style="color: #660033;"&gt;--cpu&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"4096"&lt;/span&gt; \
  &lt;span style="color: #660033;"&gt;--memory&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"30720"&lt;/span&gt; \
  &lt;span style="color: #660033;"&gt;--requires-compatibilities&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"FARGATE"&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Running the Fargate Task&lt;/div&gt;
      
      &lt;div class="field field--name-field-blog-image field--type-image field--label-hidden field--items"&gt;
              &lt;div class="field--item"&gt;    &lt;img srcset="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2019-12/screencapture-eu-west-2-console-aws-amazon-ecs-home-2019-12-10-16_40_01.png?itok=Fffyjmc5 325w, https://assets.badzilla.co.uk/s3fs-public/styles/max_650x650/public/2019-12/screencapture-eu-west-2-console-aws-amazon-ecs-home-2019-12-10-16_40_01.png?itok=-mwj0Mh3 650w, https://assets.badzilla.co.uk/s3fs-public/styles/max_1300x1300/public/2019-12/screencapture-eu-west-2-console-aws-amazon-ecs-home-2019-12-10-16_40_01.png?itok=-pRD2LfJ 1300w, https://assets.badzilla.co.uk/s3fs-public/styles/max_2600x2600/public/2019-12/screencapture-eu-west-2-console-aws-amazon-ecs-home-2019-12-10-16_40_01.png?itok=9NKHks8i 2600w" sizes="(min-width: 1290px) 1290px, 100vw" src="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2019-12/screencapture-eu-west-2-console-aws-amazon-ecs-home-2019-12-10-16_40_01.png?itok=Fffyjmc5" alt="Run Task" typeof="foaf:Image" class="img-responsive" /&gt;


&lt;/div&gt;
              &lt;div class="field--item"&gt;    &lt;img srcset="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2019-12/Screenshot%202019-12-10%20at%2016.45.09.png?itok=JCu8fCFw 325w, https://assets.badzilla.co.uk/s3fs-public/styles/max_650x650/public/2019-12/Screenshot%202019-12-10%20at%2016.45.09.png?itok=nNzZaByc 650w, https://assets.badzilla.co.uk/s3fs-public/styles/max_1300x1300/public/2019-12/Screenshot%202019-12-10%20at%2016.45.09.png?itok=p62Fu_Dl 1300w, https://assets.badzilla.co.uk/s3fs-public/styles/max_2600x2600/public/2019-12/Screenshot%202019-12-10%20at%2016.45.09.png?itok=c3o8LhZS 2600w" sizes="(min-width: 1290px) 1290px, 100vw" src="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2019-12/Screenshot%202019-12-10%20at%2016.45.09.png?itok=JCu8fCFw" alt="Running Task" typeof="foaf:Image" class="img-responsive" /&gt;


&lt;/div&gt;
              &lt;div class="field--item"&gt;    &lt;img srcset="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2019-12/Screenshot%202019-12-10%20at%2016.45.19.png?itok=O0_8h9c6 325w, https://assets.badzilla.co.uk/s3fs-public/styles/max_650x650/public/2019-12/Screenshot%202019-12-10%20at%2016.45.19.png?itok=rtPVZ1nd 650w, https://assets.badzilla.co.uk/s3fs-public/styles/max_1300x1300/public/2019-12/Screenshot%202019-12-10%20at%2016.45.19.png?itok=8oFSBSK5 1300w, https://assets.badzilla.co.uk/s3fs-public/styles/max_2600x2600/public/2019-12/Screenshot%202019-12-10%20at%2016.45.19.png?itok=b8-KpJnf 2600w" sizes="(min-width: 1290px) 1290px, 100vw" src="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2019-12/Screenshot%202019-12-10%20at%2016.45.19.png?itok=O0_8h9c6" alt="All containers running" typeof="foaf:Image" class="img-responsive" /&gt;


&lt;/div&gt;
              &lt;div class="field--item"&gt;    &lt;img srcset="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2019-12/Screenshot%202019-12-10%20at%2016.46.10.png?itok=HtC-w96y 325w, https://assets.badzilla.co.uk/s3fs-public/styles/max_650x650/public/2019-12/Screenshot%202019-12-10%20at%2016.46.10.png?itok=adcaUdoh 650w, https://assets.badzilla.co.uk/s3fs-public/styles/max_1300x1300/public/2019-12/Screenshot%202019-12-10%20at%2016.46.10.png?itok=G5h9B1j2 1300w, https://assets.badzilla.co.uk/s3fs-public/styles/max_2600x2600/public/2019-12/Screenshot%202019-12-10%20at%2016.46.10.png?itok=E1G0Wpgh 2600w" sizes="(min-width: 1290px) 1290px, 100vw" src="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2019-12/Screenshot%202019-12-10%20at%2016.46.10.png?itok=HtC-w96y" alt="All containers stopped" typeof="foaf:Image" class="img-responsive" /&gt;


&lt;/div&gt;
          &lt;/div&gt;
  
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;&lt;p&gt;Once the script is executed, the task will be defined and ready to run. This can be run by creating a new shell script (or extending the one above) or by using the console. Since this blog is becoming too code focused, I'll document the running of tasks programmatically in another blog later. For now you should be able to see your task in the console and run it. See screenshot 1 above.&lt;/p&gt;

&lt;p&gt;Screenshot 2 show that the task has reached RUNNING state. If you are quick you can click on the task identifier and be taken to the more detailed screen shown in image 3 which shows all the containers that are running. &lt;/p&gt;

&lt;p&gt;Once one of the Docker images completes its activity, a signal will be sent to all the other containers to stop. In the task described in this blog, the first task to complete is the running of the automated tests. Once the tests complete, then all other containers will stop. See image 4. &lt;/p&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Did the Tests Actually Succeed?&lt;/div&gt;
      
      &lt;div class="field field--name-field-blog-image field--type-image field--label-hidden field--items"&gt;
              &lt;div class="field--item"&gt;    &lt;img srcset="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2019-12/screencapture-eu-west-2-console-aws-amazon-cloudwatch-home-2019-12-10-16_55_13.png?itok=E8ySuBsU 325w, https://assets.badzilla.co.uk/s3fs-public/styles/max_650x650/public/2019-12/screencapture-eu-west-2-console-aws-amazon-cloudwatch-home-2019-12-10-16_55_13.png?itok=TvSbKodT 650w, https://assets.badzilla.co.uk/s3fs-public/styles/max_1300x1300/public/2019-12/screencapture-eu-west-2-console-aws-amazon-cloudwatch-home-2019-12-10-16_55_13.png?itok=kMWLfPE5 1300w, https://assets.badzilla.co.uk/s3fs-public/styles/max_2600x2600/public/2019-12/screencapture-eu-west-2-console-aws-amazon-cloudwatch-home-2019-12-10-16_55_13.png?itok=PnCz6kAM 2600w" sizes="(min-width: 1290px) 1290px, 100vw" src="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2019-12/screencapture-eu-west-2-console-aws-amazon-cloudwatch-home-2019-12-10-16_55_13.png?itok=E8ySuBsU" alt="CloudWatch success" typeof="foaf:Image" class="img-responsive" /&gt;


&lt;/div&gt;
          &lt;/div&gt;
  
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;&lt;p&gt;A valid question! The output of the Maven container is written to a CloudWatch log stream which can be parsed and echoed back to the screen, or sent to a Slack channel (more on this in a later blog). For now I have created a sequence of commands using pipes which includes the open source &lt;strong&gt;awslogs&lt;/strong&gt; utility.&lt;/p&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;$ aws logs describe-log-streams &lt;span style="color: #660033;"&gt;--log-group-name&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"/ecs/selenium-testing"&lt;/span&gt; &lt;span style="color: #660033;"&gt;--log-stream-name-prefix&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"ecs/Maven"&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; jq &lt;span style="color: #ff0000;"&gt;'.logStreams|=sort_by(-.creationTime)|.logStreams[0].logeamName'&lt;/span&gt; &lt;span style="color: #660033;"&gt;-r&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;xargs&lt;/span&gt; -I&lt;span style="color: #7a0874; font-weight: bold;"&gt;{&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;}&lt;/span&gt; awslogs get &lt;span style="color: #ff0000;"&gt;"/ecs/selenium-testing"&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;{&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;}&lt;/span&gt; &lt;span style="color: #660033;"&gt;-s1d&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;cut&lt;/span&gt; &lt;span style="color: #660033;"&gt;-d&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;' '&lt;/span&gt; &lt;span style="color: #660033;"&gt;-f&lt;/span&gt; &lt;span style="color: #000000;"&gt;1&lt;/span&gt;,&lt;span style="color: #000000;"&gt;2&lt;/span&gt; &lt;span style="color: #660033;"&gt;--complement&lt;/span&gt;
mvn
&lt;span style="color: #660033;"&gt;-------------------------------------------------------&lt;/span&gt;
 T E S T S
&lt;span style="color: #660033;"&gt;-------------------------------------------------------&lt;/span&gt;
Running mytests.RunCucumberTest
Dec &lt;span style="color: #000000;"&gt;10&lt;/span&gt;, &lt;span style="color: #000000;"&gt;2019&lt;/span&gt; &lt;span style="color: #000000;"&gt;3&lt;/span&gt;:&lt;span style="color: #000000;"&gt;43&lt;/span&gt;:&lt;span style="color: #000000;"&gt;46&lt;/span&gt; PM org.openqa.selenium.remote.ProtocolHandshake createSession
INFO: Detected dialect: W3C
Dec &lt;span style="color: #000000;"&gt;10&lt;/span&gt;, &lt;span style="color: #000000;"&gt;2019&lt;/span&gt; &lt;span style="color: #000000;"&gt;3&lt;/span&gt;:&lt;span style="color: #000000;"&gt;43&lt;/span&gt;:&lt;span style="color: #000000;"&gt;47&lt;/span&gt; PM org.openqa.selenium.remote.ProtocolHandshake createSession
INFO: Detected dialect: W3C
Dec &lt;span style="color: #000000;"&gt;10&lt;/span&gt;, &lt;span style="color: #000000;"&gt;2019&lt;/span&gt; &lt;span style="color: #000000;"&gt;3&lt;/span&gt;:&lt;span style="color: #000000;"&gt;43&lt;/span&gt;:&lt;span style="color: #000000;"&gt;49&lt;/span&gt; PM org.openqa.selenium.remote.ProtocolHandshake createSession
INFO: Detected dialect: W3C
Dec &lt;span style="color: #000000;"&gt;10&lt;/span&gt;, &lt;span style="color: #000000;"&gt;2019&lt;/span&gt; &lt;span style="color: #000000;"&gt;3&lt;/span&gt;:&lt;span style="color: #000000;"&gt;43&lt;/span&gt;:&lt;span style="color: #000000;"&gt;50&lt;/span&gt; PM org.openqa.selenium.remote.ProtocolHandshake createSession
INFO: Detected dialect: W3C
Feature: Are we on the Home Page?
  Scenario: On the home page         &lt;span style="color: #666666; font-style: italic;"&gt;# mytests/home_page.feature:4&lt;/span&gt;
    When User is on the Home Page    &lt;span style="color: #666666; font-style: italic;"&gt;# Stepdefs.user_is_on_Home_Page()&lt;/span&gt;
    Then Message Displayed Memcached &lt;span style="color: #666666; font-style: italic;"&gt;# Stepdefs.message_displayed_memcached()&lt;/span&gt;
    When User is on the Home Page    &lt;span style="color: #666666; font-style: italic;"&gt;# Stepdefs.user_is_on_Home_Page()&lt;/span&gt;
    Then Message Displayed GD        &lt;span style="color: #666666; font-style: italic;"&gt;# Stepdefs.gd()&lt;/span&gt;
&lt;span style="color: #000000;"&gt;1&lt;/span&gt; Scenarios &lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;&lt;span style="color: #000000;"&gt;1&lt;/span&gt; passed&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;
&lt;span style="color: #000000;"&gt;4&lt;/span&gt; Steps &lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;&lt;span style="color: #000000;"&gt;4&lt;/span&gt; passed&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;
0m6.835s
Tests run: &lt;span style="color: #000000;"&gt;1&lt;/span&gt;, Failures: &lt;span style="color: #000000;"&gt;0&lt;/span&gt;, Errors: &lt;span style="color: #000000;"&gt;0&lt;/span&gt;, Skipped: &lt;span style="color: #000000;"&gt;0&lt;/span&gt;, Time elapsed: &lt;span style="color: #000000;"&gt;7.055&lt;/span&gt; sec
Results :
Tests run: &lt;span style="color: #000000;"&gt;1&lt;/span&gt;, Failures: &lt;span style="color: #000000;"&gt;0&lt;/span&gt;, Errors: &lt;span style="color: #000000;"&gt;0&lt;/span&gt;, Skipped: &lt;span style="color: #000000;"&gt;0&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Troubleshooting Selenium Grid&lt;/div&gt;
      
      &lt;div class="field field--name-field-blog-image field--type-image field--label-hidden field--items"&gt;
              &lt;div class="field--item"&gt;    &lt;img srcset="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2019-12/Screenshot%202019-12-10%20at%2017.17.52.png?itok=CyMh5g8X 325w, https://assets.badzilla.co.uk/s3fs-public/styles/max_650x650/public/2019-12/Screenshot%202019-12-10%20at%2017.17.52.png?itok=uKKQA2e6 650w, https://assets.badzilla.co.uk/s3fs-public/styles/max_1300x1300/public/2019-12/Screenshot%202019-12-10%20at%2017.17.52.png?itok=XEv9FUiO 1300w, https://assets.badzilla.co.uk/s3fs-public/styles/max_2600x2600/public/2019-12/Screenshot%202019-12-10%20at%2017.17.52.png?itok=UcTRu0a3 2600w" sizes="(min-width: 1290px) 1290px, 100vw" src="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2019-12/Screenshot%202019-12-10%20at%2017.17.52.png?itok=CyMh5g8X" alt="Custom Rule" typeof="foaf:Image" class="img-responsive" /&gt;


&lt;/div&gt;
              &lt;div class="field--item"&gt;    &lt;img srcset="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2019-12/Screenshot%202019-12-10%20at%2017.18.24.png?itok=3Jg4RYn9 325w, https://assets.badzilla.co.uk/s3fs-public/styles/max_650x650/public/2019-12/Screenshot%202019-12-10%20at%2017.18.24.png?itok=xTq_OE_n 650w, https://assets.badzilla.co.uk/s3fs-public/styles/max_1300x1300/public/2019-12/Screenshot%202019-12-10%20at%2017.18.24.png?itok=aNF-w9z5 1300w, https://assets.badzilla.co.uk/s3fs-public/styles/max_2600x2600/public/2019-12/Screenshot%202019-12-10%20at%2017.18.24.png?itok=EuDe0bIn 2600w" sizes="(min-width: 1290px) 1290px, 100vw" src="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2019-12/Screenshot%202019-12-10%20at%2017.18.24.png?itok=3Jg4RYn9" alt="Selenium Grid" typeof="foaf:Image" class="img-responsive" /&gt;


&lt;/div&gt;
          &lt;/div&gt;
  
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;&lt;p&gt;Getting the Selenium stack working can be fiddly, although the CloudWatch logs are a very good way of diagnosing problems. If you want to satisy yourself that Selenium Hub and its two nodes (Firefox and Chrome) are actually there and available, there is a way but you'll have to work fast on the console since the Fargate tasks completes and shuts down once the tests are complete. &lt;/p&gt;

&lt;p&gt;When the Fargate task transitions from PENDING to RUNNING, click on the task identifier. Copy the public IP address into your clipboard - you'll need it shortly. Now click on the ENI (Elastic Network Interface) link which will launch a new tab. Then click on the security group. Now you need to create a new rule. By default port 4444 is blocked on the public IP address - and to see Selenium working I need that to be open. &lt;/p&gt;

&lt;p&gt;Edit the rules, create a new custom TCP/IP rule, add 4444 as the port and select anywhere for the CIDR, then save. See screenshot 1 above. &lt;/p&gt;

&lt;p&gt;You now instantly have an open port 4444. Open a new browser tab, then paste the IP address you copied a few steps ago, then append /grid/console to it and enter. You should see your Grid + Node configuration as per the second screenshot above. &lt;/p&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
          &lt;/div&gt;
  
      &lt;div class="field field--name-field-blog-youtube field--type-entity-reference-revisions field--label-hidden field--items"&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-text-youtube paragraph--view-mode--default"&gt;
          
      &lt;/div&gt;
&lt;/div&gt;
          &lt;/div&gt;
  
  &lt;div class="field field--name-field-blog-terms field--type-entity-reference field--label-inline"&gt;
    &lt;div class="field--label"&gt;blog terms&lt;/div&gt;
          &lt;span class="field__items"&gt;
              &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/devops" hreflang="en"&gt;devops&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/ecs" hreflang="en"&gt;ECS&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/aws" hreflang="en"&gt;AWS&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/awscli" hreflang="en"&gt;AWS CLI&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/development" hreflang="en"&gt;Development&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/docker" hreflang="en"&gt;Docker&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/bash" hreflang="en"&gt;bash&lt;/a&gt;&lt;/span&gt;
              &lt;/span&gt;
      &lt;/div&gt;
</description>
  <pubDate>Mon, 09 Dec 2019 08:37:50 +0000</pubDate>
    <dc:creator>nigel</dc:creator>
    <guid isPermaLink="false">173 at http://badzilla.co.uk</guid>
    </item>
<item>
  <title>Programmatically Create AWS ECR Repository and Commit Docker Image to ECR</title>
  <link>http://badzilla.co.uk/programmatically-create-aws-ecr-repository-and-commit-docker-image-ecr</link>
  <description>
&lt;span&gt;Programmatically Create AWS ECR Repository and Commit Docker Image to ECR&lt;/span&gt;

&lt;span&gt;&lt;span lang="" about="http://badzilla.co.uk/user/1" typeof="schema:Person" property="schema:name" datatype="" xml:lang=""&gt;nigel&lt;/span&gt;&lt;/span&gt;

&lt;span&gt;Sat, 07/12/2019 - 07:56&lt;/span&gt;

      &lt;div class="field field--name-field-heading-image-text field--type-entity-reference-revisions field--label-hidden field--items"&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;&lt;p&gt;This is a tutorial for using AWS CLI to programmatically create an AWS ECR repository and then commit a Docker image to that repository. This is the first step in a series of tutorials for creating an automated testing framework in AWS Fargate which can be one step of a DevOps pipeline. &lt;/p&gt;

&lt;p&gt;As an example I am going to use the Docker php:7.2-apache image and to make it a little more complex, add a few more PHP extensions using a new Dockerfile so that my new image will be Drupal 8 compliant. &lt;/p&gt;

&lt;p&gt;Let's get started. &lt;/p&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Pull Base Image and Define Dockerfile&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;The base php:7.2-apache image needs to be pulled from Docker Hub. Issue the following command. 
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;$ docker pull php:&lt;span style="color: #000000;"&gt;7.2&lt;/span&gt;-apache
&lt;span style="color: #000000;"&gt;7.2&lt;/span&gt;-apache: Pulling from library&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;php
000eee12ec04: Pull &lt;span style="color: #7a0874; font-weight: bold;"&gt;complete&lt;/span&gt; 
8ae4f9fcfeea: Pull &lt;span style="color: #7a0874; font-weight: bold;"&gt;complete&lt;/span&gt; 
60f22fbbd07a: Pull &lt;span style="color: #7a0874; font-weight: bold;"&gt;complete&lt;/span&gt; 
ccc7a63ad75f: Pull &lt;span style="color: #7a0874; font-weight: bold;"&gt;complete&lt;/span&gt; 
a2427b8dd6e7: Pull &lt;span style="color: #7a0874; font-weight: bold;"&gt;complete&lt;/span&gt; 
91cac3b30184: Pull &lt;span style="color: #7a0874; font-weight: bold;"&gt;complete&lt;/span&gt; 
d6e40015fc10: Pull &lt;span style="color: #7a0874; font-weight: bold;"&gt;complete&lt;/span&gt; 
240e21c03bb4: Pull &lt;span style="color: #7a0874; font-weight: bold;"&gt;complete&lt;/span&gt; 
504858e1e4aa: Pull &lt;span style="color: #7a0874; font-weight: bold;"&gt;complete&lt;/span&gt; 
9a0523b2d73f: Pull &lt;span style="color: #7a0874; font-weight: bold;"&gt;complete&lt;/span&gt; 
e3acb84829f4: Pull &lt;span style="color: #7a0874; font-weight: bold;"&gt;complete&lt;/span&gt; 
28a372733f87: Pull &lt;span style="color: #7a0874; font-weight: bold;"&gt;complete&lt;/span&gt; 
62ee66cdb80a: Pull &lt;span style="color: #7a0874; font-weight: bold;"&gt;complete&lt;/span&gt; 
c3f368ddc7aa: Pull &lt;span style="color: #7a0874; font-weight: bold;"&gt;complete&lt;/span&gt; 
Digest: sha256:602bef9acc8d54527ae5b7ee0f16e5cdb6ab81364310f5123b93b95e357f608d
Status: Downloaded newer image &lt;span style="color: #000000; font-weight: bold;"&gt;for&lt;/span&gt; php:&lt;span style="color: #000000;"&gt;7.2&lt;/span&gt;-apache
docker.io&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;library&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;php:&lt;span style="color: #000000;"&gt;7.2&lt;/span&gt;-apache
$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
php                 &lt;span style="color: #000000;"&gt;7.2&lt;/span&gt;-apache          fec8a1aaffb8        &lt;span style="color: #000000;"&gt;31&lt;/span&gt; hours ago        410MB
lambci&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;lambda       go1.x               8d962cde7e27        &lt;span style="color: #000000;"&gt;3&lt;/span&gt; months ago        707MB
sls-docker          latest              8d962cde7e27        &lt;span style="color: #000000;"&gt;3&lt;/span&gt; months ago        707MB&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
Yes the docker image is there. Now I need to create a directory for the Dockerfile and a sample index.php file which will prove our image is working. 
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #666666;"&gt;$ &lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;mkdir&lt;/span&gt; automated &lt;span style="color: #000000; font-weight: bold;"&gt;&amp;&amp;&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;cd&lt;/span&gt; automated&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
By default the Docker php image uses /var/www/html as Apache's docroot. However, I'm going to alter this to something more standard for Drupal web apps - a directory called docroot will be created and will contain a simple index.php containing a call to phpinfo();
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #666666;"&gt;$ &lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;mkdir&lt;/span&gt; docroot &lt;span style="color: #000000; font-weight: bold;"&gt;&amp;&amp;&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;?php phpinfo();"&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt; docroot&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;index.php&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
The Dockerfile should now be created and populated. There a number of activities that need to be performed on it. 
&lt;ul&gt;
&lt;li&gt;Reference the base image with a FROM instruction&lt;/li&gt;
&lt;li&gt;Install the libraries that support memcached and graphics manipulation&lt;/li&gt;
&lt;li&gt;Enable memcached PHP extension&lt;/li&gt;
&lt;li&gt;Configure the graphics PHP extension&lt;/li&gt;
&lt;li&gt;Install the graphics PHP extension&lt;/li&gt;
&lt;li&gt;Copy the files in the current directory and below into the Docker image at the /var/www/html ensuring the permissions are correct for the apache user and group&lt;/li&gt;
&lt;li&gt;Set the environment variable AH_SITE_ENVIRONMENT to devops - this is an Acquia Cloud environment variable and only of any significance for those using Acquia as their host - or need a setting in my case to denote that devops is not running on Acquia&lt;/li&gt;
&lt;li&gt;Change the default location for the docroot - that means setting an environment variable and using the sed editor to change the configuration in the sites files&lt;/li&gt;
&lt;/ul&gt;
&lt;strong&gt;Dockerfile&lt;/strong&gt;
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;FROM php:&lt;span style="color: #000000;"&gt;7.2&lt;/span&gt;-apache
RUN &lt;span style="color: #c20cb9; font-weight: bold;"&gt;apt-get update&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;&amp;&amp;&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;apt-get install&lt;/span&gt; &lt;span style="color: #660033;"&gt;-y&lt;/span&gt; libmemcached-dev zlib1g-dev \
    libfreetype6-dev \
    libjpeg62-turbo-dev \
    libpng-dev \
    libwebp-dev \
    &lt;span style="color: #000000; font-weight: bold;"&gt;&amp;&amp;&lt;/span&gt; pecl &lt;span style="color: #c20cb9; font-weight: bold;"&gt;install&lt;/span&gt; memcached \
    &lt;span style="color: #000000; font-weight: bold;"&gt;&amp;&amp;&lt;/span&gt; docker-php-ext-enable memcached \
    &lt;span style="color: #000000; font-weight: bold;"&gt;&amp;&amp;&lt;/span&gt; docker-php-ext-configure gd &lt;span style="color: #660033;"&gt;--with-gd&lt;/span&gt; &lt;span style="color: #660033;"&gt;--with-webp-dir&lt;/span&gt; &lt;span style="color: #660033;"&gt;--with-jpeg-dir&lt;/span&gt; \
       &lt;span style="color: #660033;"&gt;--with-png-dir&lt;/span&gt; &lt;span style="color: #660033;"&gt;--with-zlib-dir&lt;/span&gt; &lt;span style="color: #660033;"&gt;--with-freetype-dir&lt;/span&gt; \
    &lt;span style="color: #000000; font-weight: bold;"&gt;&amp;&amp;&lt;/span&gt; docker-php-ext-install gd
COPY &lt;span style="color: #660033;"&gt;--chown&lt;/span&gt;=www-data:www-data .&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;var&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;www&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;html&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;.
ENV AH_SITE_ENVIRONMENT devops
ENV APACHE_DOCUMENT_ROOT &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;var&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;www&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;html&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;docroot
RUN &lt;span style="color: #c20cb9; font-weight: bold;"&gt;sed&lt;/span&gt; &lt;span style="color: #660033;"&gt;-ri&lt;/span&gt; &lt;span style="color: #660033;"&gt;-e&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;'s!/var/www/html!${APACHE_DOCUMENT_ROOT}!g'&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;etc&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;apache2&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;sites-available&lt;span style="color: #000000; font-weight: bold;"&gt;/*&lt;/span&gt;.conf
RUN &lt;span style="color: #c20cb9; font-weight: bold;"&gt;sed&lt;/span&gt; &lt;span style="color: #660033;"&gt;-ri&lt;/span&gt; &lt;span style="color: #660033;"&gt;-e&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;'s!/var/www/!${APACHE_DOCUMENT_ROOT}!g'&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;etc&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;apache2&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;apache2.conf &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;etc&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;apache2&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;conf-available&lt;span style="color: #000000; font-weight: bold;"&gt;/*&lt;/span&gt;.conf&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Build the Image, Run the Container&lt;/div&gt;
      
      &lt;div class="field field--name-field-blog-image field--type-image field--label-hidden field--items"&gt;
              &lt;div class="field--item"&gt;    &lt;img srcset="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2019-12/Screenshot%202019-12-07%20at%2012.17.34.png?itok=jwU0kVpn 325w, https://assets.badzilla.co.uk/s3fs-public/styles/max_650x650/public/2019-12/Screenshot%202019-12-07%20at%2012.17.34.png?itok=XLFrcLyd 650w, https://assets.badzilla.co.uk/s3fs-public/styles/max_1300x1300/public/2019-12/Screenshot%202019-12-07%20at%2012.17.34.png?itok=7J5O5LHx 1300w, https://assets.badzilla.co.uk/s3fs-public/styles/max_2600x2600/public/2019-12/Screenshot%202019-12-07%20at%2012.17.34.png?itok=eCD6F2Tg 2310w" sizes="(min-width: 1290px) 1290px, 100vw" src="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2019-12/Screenshot%202019-12-07%20at%2012.17.34.png?itok=jwU0kVpn" alt="phpinfo" typeof="foaf:Image" class="img-responsive" /&gt;


&lt;/div&gt;
          &lt;/div&gt;
  
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;Once the Dockerfile is complete, it is built with
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #666666;"&gt;$ &lt;/span&gt;docker build &lt;span style="color: #660033;"&gt;-t&lt;/span&gt; d8codebase .&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
and to confirm it's built correctly:
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
d8codebase          latest              c2193f9778a6        &lt;span style="color: #000000;"&gt;33&lt;/span&gt; minutes ago      439MB
&lt;span style="color: #000000; font-weight: bold;"&gt;&lt;&lt;/span&gt;none&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;              &lt;span style="color: #000000; font-weight: bold;"&gt;&lt;&lt;/span&gt;none&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;              2a71964685e0        &lt;span style="color: #000000;"&gt;2&lt;/span&gt; hours ago         432MB
php                 &lt;span style="color: #000000;"&gt;7.2&lt;/span&gt;-apache          fec8a1aaffb8        &lt;span style="color: #000000;"&gt;35&lt;/span&gt; hours ago        410MB
lambci&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;lambda       go1.x               8d962cde7e27        &lt;span style="color: #000000;"&gt;3&lt;/span&gt; months ago        707MB
sls-docker          latest              8d962cde7e27        &lt;span style="color: #000000;"&gt;3&lt;/span&gt; months ago        707MB&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
Great it's there. Now to spin up the container. 
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #666666;"&gt;$ &lt;/span&gt;docker run &lt;span style="color: #660033;"&gt;-d&lt;/span&gt; &lt;span style="color: #660033;"&gt;-p&lt;/span&gt; &lt;span style="color: #000000;"&gt;8080&lt;/span&gt;:&lt;span style="color: #000000;"&gt;80&lt;/span&gt; d8codebase&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
Note I am mapping port 8080 to the container's port 80 which probably won't be pertinent to you. Long story I will try to make short. I write my blogs on my Macbook on a local network in the 192.168 range assigned by my ISP's hub. But I develop and test all the practical work in my blogs in a VM in the IP 10. range. Routing between 192.168 and 10. is difficult without port forwarding - so I port forward 127.0.0.1 8080 to my VM's 10.0.2.15 8080, so when I run my Docker Apache container I must remember incoming is on port 8080 and map that against the container's port 80. Hope that makes sense!&lt;br /&gt;&lt;br /&gt;Now check it's running:
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;$ docker &lt;span style="color: #c20cb9; font-weight: bold;"&gt;ps&lt;/span&gt;
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
9a6dc2fb88ff        d8codebase          &lt;span style="color: #ff0000;"&gt;"docker-php-entrypoi…"&lt;/span&gt;   &lt;span style="color: #000000;"&gt;44&lt;/span&gt; minutes ago      Up &lt;span style="color: #000000;"&gt;44&lt;/span&gt; minutes       0.0.0.0:&lt;span style="color: #000000;"&gt;8080&lt;/span&gt;-&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;80&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;tcp   agitated_feistel&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
Yes, and we can see from the screenshot above that it's picking up the memcached and the gd graphics extensions. Success.&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Programmatically Create the AWS ECR Repository&lt;/div&gt;
      
      &lt;div class="field field--name-field-blog-image field--type-image field--label-hidden field--items"&gt;
              &lt;div class="field--item"&gt;    &lt;img srcset="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2019-12/Screenshot_2019-12-07_at_13_16_14-edited.png?itok=eiXr6OXC 325w, https://assets.badzilla.co.uk/s3fs-public/styles/max_650x650/public/2019-12/Screenshot_2019-12-07_at_13_16_14-edited.png?itok=6-TIckwl 650w, https://assets.badzilla.co.uk/s3fs-public/styles/max_1300x1300/public/2019-12/Screenshot_2019-12-07_at_13_16_14-edited.png?itok=inIVYe9n 1300w, https://assets.badzilla.co.uk/s3fs-public/styles/max_2600x2600/public/2019-12/Screenshot_2019-12-07_at_13_16_14-edited.png?itok=cBSia9gB 2600w" sizes="(min-width: 1290px) 1290px, 100vw" src="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2019-12/Screenshot_2019-12-07_at_13_16_14-edited.png?itok=eiXr6OXC" alt="ECR Repository" typeof="foaf:Image" class="img-responsive" /&gt;


&lt;/div&gt;
          &lt;/div&gt;
  
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;This is quite easy and I've put it into a shell script that requires one parameter - the repo name to be created. The work is done by the aws ecr create-repository call. The rest of the code is simply checking for error conditions. The screenshot above was taken on the AWS console after the shell script below was successfully run with a parameter of d8codebase.
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #666666; font-style: italic;"&gt;#!/bin/bash&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;#Programmatically create an ECR repo&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Check whether we have the args&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #660033;"&gt;-z&lt;/span&gt; $&lt;span style="color: #000000; font-weight: bold;"&gt;@&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"usage: [repo_name]"&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;exit&lt;/span&gt; &lt;span style="color: #000000;"&gt;1&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Create the repo&lt;/span&gt;
&lt;span style="color: #007800;"&gt;REPO_NAME&lt;/span&gt;=&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;aws ecr create-repository &lt;span style="color: #660033;"&gt;--repository-name&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"$1"&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; jq .repository.repositoryName -r&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Check it was created ok. We already get a quality stderr msg from aws cli so just quit on error.&lt;/span&gt;
&lt;span style="color: #666666; font-style: italic;"&gt;# Similarly, if already exists it will tell us&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${REPO_NAME}&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;!&lt;/span&gt;= &lt;span style="color: #007800;"&gt;$1&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;exit&lt;/span&gt; &lt;span style="color: #000000;"&gt;2&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;
 
&lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"Successfully created &lt;span style="color: #007800;"&gt;${REPO_NAME}&lt;/span&gt;"&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Login to Docker and Push Image to ECR&lt;/div&gt;
      
      &lt;div class="field field--name-field-blog-image field--type-image field--label-hidden field--items"&gt;
              &lt;div class="field--item"&gt;    &lt;img srcset="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2019-12/Screenshot_2019-12-08_at_10_20_26-edited.png?itok=sv0QPbaX 325w, https://assets.badzilla.co.uk/s3fs-public/styles/max_650x650/public/2019-12/Screenshot_2019-12-08_at_10_20_26-edited.png?itok=AEUf4O-_ 650w, https://assets.badzilla.co.uk/s3fs-public/styles/max_1300x1300/public/2019-12/Screenshot_2019-12-08_at_10_20_26-edited.png?itok=z9aPZ3kh 1300w, https://assets.badzilla.co.uk/s3fs-public/styles/max_2600x2600/public/2019-12/Screenshot_2019-12-08_at_10_20_26-edited.png?itok=JirTlXB0 2600w" sizes="(min-width: 1290px) 1290px, 100vw" src="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2019-12/Screenshot_2019-12-08_at_10_20_26-edited.png?itok=sv0QPbaX" alt="Docker Push" typeof="foaf:Image" class="img-responsive" /&gt;


&lt;/div&gt;
          &lt;/div&gt;
  
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;Now the script to automatically login to Docker and push the image to ECR. Note that AWS ECR does require you to use the docker login command, and therefore provides a AWS CLI ECR command get-login which returns a token than can be piped into the docker login command. The token retrieved from ECR has a large payload, and it is top and tailed with other metadata beyond just the password. Therefore that needs to be removed, and if you look closely at the script below, you can see that I pipe the entire returned payload through sed with a regex, and then the result is piped onwards to docker login. Hopefully the rest is quite self explanatory - and you can see the screenshot above that the push has worked and the image can now be included in ECS / Fargate task definitions. 
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #666666; font-style: italic;"&gt;#!/bin/bash&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;#Programmatically push to an ECR repo&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Check whether we have the args&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #660033;"&gt;-z&lt;/span&gt; $&lt;span style="color: #000000; font-weight: bold;"&gt;@&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"usage: [repo_name]"&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;exit&lt;/span&gt; &lt;span style="color: #000000;"&gt;1&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;
 
&lt;span style="color: #007800;"&gt;REPO_NAME&lt;/span&gt;=&lt;span style="color: #007800;"&gt;$1&lt;/span&gt;
&lt;span style="color: #007800;"&gt;ECR_ACCOUNT&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;"XXXXXXXXXX.dkr.ecr.eu-west-2.amazonaws.com"&lt;/span&gt;
&lt;span style="color: #007800;"&gt;ECR_REPO&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${ECR_ACCOUNT}&lt;/span&gt;/$1"&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;# AWS Authentication - since we need to use docker push&lt;/span&gt;
&lt;span style="color: #666666; font-style: italic;"&gt;# The sed regex will top and tail the additional meta data sent by the aws login request.&lt;/span&gt;
aws ecr get-login &lt;span style="color: #660033;"&gt;--region&lt;/span&gt; eu-west-&lt;span style="color: #000000;"&gt;2&lt;/span&gt;  &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;sed&lt;/span&gt; &lt;span style="color: #660033;"&gt;-e&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;'s/^.*-p \(.*\)\s\-\e.*$/\1/'&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt;  docker &lt;span style="color: #c20cb9; font-weight: bold;"&gt;login&lt;/span&gt; &lt;span style="color: #660033;"&gt;--password-stdin&lt;/span&gt; &lt;span style="color: #660033;"&gt;-u&lt;/span&gt; AWS &lt;span style="color: #800000;"&gt;${ECR_ACCOUNT}&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Get the image id of the Docker build. If there is a "latest" use that else get the first without latest&lt;/span&gt;
&lt;span style="color: #007800;"&gt;TAG&lt;/span&gt;=&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;docker images &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;grep&lt;/span&gt; &lt;span style="color: #660033;"&gt;-w&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${REPO_NAME}&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;grep&lt;/span&gt; latest &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;awk&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;'{ print $3; }'&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #660033;"&gt;-z&lt;/span&gt; &lt;span style="color: #800000;"&gt;${TAG}&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
        &lt;span style="color: #007800;"&gt;TAG&lt;/span&gt;=&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;docker images &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;grep&lt;/span&gt; &lt;span style="color: #660033;"&gt;-w&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${REPO_NAME}&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;awk&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;'{ print $3; }'&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;
 
docker tag &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$TAG&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${ECR_REPO}&lt;/span&gt;"&lt;/span&gt;
docker push &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;${ECR_REPO}&lt;/span&gt;"&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
          &lt;/div&gt;
  
      &lt;div class="field field--name-field-blog-youtube field--type-entity-reference-revisions field--label-hidden field--items"&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-text-youtube paragraph--view-mode--default"&gt;
          
      &lt;/div&gt;
&lt;/div&gt;
          &lt;/div&gt;
  
  &lt;div class="field field--name-field-blog-terms field--type-entity-reference field--label-inline"&gt;
    &lt;div class="field--label"&gt;blog terms&lt;/div&gt;
          &lt;span class="field__items"&gt;
              &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/aws" hreflang="en"&gt;AWS&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/awscli" hreflang="en"&gt;AWS CLI&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/docker" hreflang="en"&gt;Docker&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/devops" hreflang="en"&gt;devops&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/fargate" hreflang="en"&gt;Fargate&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/ecs" hreflang="en"&gt;ECS&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/development" hreflang="en"&gt;Development&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/bash" hreflang="en"&gt;bash&lt;/a&gt;&lt;/span&gt;
              &lt;/span&gt;
      &lt;/div&gt;
</description>
  <pubDate>Sat, 07 Dec 2019 07:56:15 +0000</pubDate>
    <dc:creator>nigel</dc:creator>
    <guid isPermaLink="false">172 at http://badzilla.co.uk</guid>
    </item>
<item>
  <title>Create Arbitrary Subdomains for AWS Fargate Tasks using AWS CLI</title>
  <link>http://badzilla.co.uk/create-arbitrary-subdomains-aws-fargate-tasks-using-aws-cli</link>
  <description>
&lt;span&gt;Create Arbitrary Subdomains for AWS Fargate Tasks using AWS CLI&lt;/span&gt;

&lt;span&gt;&lt;span lang="" about="http://badzilla.co.uk/user/1" typeof="schema:Person" property="schema:name" datatype="" xml:lang=""&gt;nigel&lt;/span&gt;&lt;/span&gt;

&lt;span&gt;Fri, 01/11/2019 - 15:03&lt;/span&gt;

      &lt;div class="field field--name-field-heading-image-text field--type-entity-reference-revisions field--label-hidden field--items"&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
      &lt;div class="field field--name-field-blog-image field--type-image field--label-hidden field--items"&gt;
              &lt;div class="field--item"&gt;    &lt;img srcset="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2019-11/Screenshot_2019-11-03_at_11_24_32-edited1.png?itok=t3-00HWu 325w, https://assets.badzilla.co.uk/s3fs-public/styles/max_650x650/public/2019-11/Screenshot_2019-11-03_at_11_24_32-edited1.png?itok=dcZAK-DY 650w, https://assets.badzilla.co.uk/s3fs-public/styles/max_1300x1300/public/2019-11/Screenshot_2019-11-03_at_11_24_32-edited1.png?itok=aY5EToiP 1300w, https://assets.badzilla.co.uk/s3fs-public/styles/max_2600x2600/public/2019-11/Screenshot_2019-11-03_at_11_24_32-edited1.png?itok=MUHYEW-M 1695w" sizes="(min-width: 1290px) 1290px, 100vw" src="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2019-11/Screenshot_2019-11-03_at_11_24_32-edited1.png?itok=t3-00HWu" alt="Success" typeof="foaf:Image" class="img-responsive" /&gt;


&lt;/div&gt;
          &lt;/div&gt;
  
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;&lt;p&gt;AWS Fargate is a relatively new product offering the capability of running Docker bundles as an ECS compute service on EC2 without the necessity for the user to have to orchestrate the underlying EC2 infrastructure. It is perfect for DevOps, and was the technology I chose as DevOps Architect at my current client. The client wanted standard CI/CD capabilities such as spinning up containerised copies of their website environment per feature branch to perform static analysis, automated testing, and also significantly, a persisting playground that QA or development personnel could use for manual testing and troubleshooting a feature (or hotfix) branch they are currently working on.&lt;/p&gt;

&lt;p&gt;This is similar to the offering of both Platform.sh and Amazee Labs hosting solutions - developers can spin up their feature branches. Alas my client is locked into another host yet needed on-the-fly feature branch Docker bundles.&lt;/p&gt;

&lt;p&gt;AWS Fargate tasks can achieve this, but out of the box it isn't possible to create public domain registration via ECS Service Discovery. The Fargate task is issued a bare IPv4 address which will obviously work but our requirement is to have a subdomain created per branch that would be of the format {hotfix|feature}--{jira ticket}-{suitable branch name}.{top level domain}.  So an example would be:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;feature--doi-746-my-whizzy-new-feature.clientdomain.dev&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So whilst we can't create a subdomain like that natively, we can do it by retrieving the IP address from the ECS Fargate task, then add that IP to a public Route 53 Hosted Zone. Furthermore, since the Fargate task is run via a Jenkins pipeline job that uses shell scripts populated with AWS CLI, the good news is we can indeed complete the registration of subdomain also using the AWS CLI *and* have the DNS propagate within 60 seconds! Amazing! Let's dive into how we achieve this. &lt;/p&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Requirements + Assumptions&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;&lt;p&gt;The solution will be built using the standard httpd Apache2 server sample Fargate task described on the AWS blog &lt;a href="https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ECS_AWSCLI_Fargate.html"&gt;Tutorial: Creating a Cluster with a Fargate Task Using the AWS CLI&lt;/a&gt;. I added the task definition into the console, although it is also possible create a shell script and use AWS CLI. I have used the default cluster for brevity's sake, and the AWS account default VPC. I have also transferred a spare domain I had, &lt;em&gt;saasidate.com&lt;/em&gt;, into Route 53 before I started the blog. This will be my tld and all the subdomains will be added off it. It's important that the ownership of the domain is transferred into Route 53 since otherwise subdomains will have authority issues if the parent domain is still registered to other domain providers such as GoDaddy or 123-Reg. &lt;/p&gt;
&lt;p&gt;The solution I am putting together will use AWS CLI which by default returns JSON structured data. It is absolutely essential to use the Linux command line utility &lt;strong&gt;jq&lt;/strong&gt; for parsing the JSON. Documentation on jq is readily available on the net. &lt;/p&gt;
&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Steps&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;&lt;p&gt;The solution will need the following steps:&lt;/p&gt;

&lt;ol&gt;
	&lt;li&gt;Get the user's default VPC (or create a custom VPC if preferred. We'll need this at a few points in the code. &lt;/li&gt;
	&lt;li&gt;Get a subnet from the VPC. Three subnets are created for use with the default VPC. I pick the first which is arbitrary.&lt;/li&gt;
	&lt;li&gt;Get a security group. A new security group is created per task when using the console but that is unnecessary for the shell scripts we will be building. So in our script, check whether our 'standard' security group has been created. If so use it, if not then create a security group with an ingress port of 80 and a CIDR of 0.0.0.0/0 which allows access worldwide on TCP port 80.&lt;/li&gt;
	&lt;li&gt;Run the Fargate task and loop / sleep until the task has a status of RUNNING. &lt;/li&gt;
	&lt;li&gt;Get the network interface id of the task and interrogate it for the IP address. &lt;/li&gt;
	&lt;li&gt;Get the hosted zone for the parent domain.&lt;/li&gt;
	&lt;li&gt;Add a record set containing the feature branch subdomain to the parent domain's hosted zone.&lt;/li&gt;
	&lt;li&gt;Create a new hosted zone using the feature branch. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Ok - let's crack on and put this into AWS CLI shell scripts. &lt;/p&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Get the VPC&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;I'm using the default VPC so I can filter the list I get back from AWS using the IsDefault attribute. 
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #007800;"&gt;VPC&lt;/span&gt;=&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;aws ec2 describe-vpcs &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; jq &lt;span style="color: #ff0000;"&gt;'.Vpcs[] | select(.IsDefault == true) | .VpcId'&lt;/span&gt; -r&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
Note the use of the jq select statement. This is a familiar construct and will be used throughout this blog. Also note the -r flag - this removes the double quotes from the response.&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Get the First Subnet in the Default VPC&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;Here I am using jq again but piping the results through head to get the first subnet. There wasn't an obvious jq query to do this natively within jq. 
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #666666; font-style: italic;"&gt;# Get the first subnet of the VPC&lt;/span&gt;
&lt;span style="color: #007800;"&gt;SUBNET&lt;/span&gt;=&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;aws ec2 describe-subnets &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; jq &lt;span style="color: #660033;"&gt;--arg&lt;/span&gt; VPC &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$VPC&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;'.Subnets[] | select(.VpcId == $VPC) | .SubnetId'&lt;/span&gt; &lt;span style="color: #660033;"&gt;-r&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;head&lt;/span&gt; &lt;span style="color: #660033;"&gt;-n&lt;/span&gt; &lt;span style="color: #000000;"&gt;1&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Get the Security Group&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;Here I check whether we already have a dedicated security group which gives us worldwide access to port 80. I search first for a unique security group description and if it doesn't exist, then create it.
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #666666; font-style: italic;"&gt;# Check if our security group for port 80 webserver already exists. Search for our funky unique description&lt;/span&gt;
&lt;span style="color: #007800;"&gt;SECURITY&lt;/span&gt;=&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;aws ec2 describe-security-groups &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; jq &lt;span style="color: #ff0000;"&gt;' .SecurityGroups[] | select (.Description == "Ingress Port 80 Anywhere") | .GroupId'&lt;/span&gt; -r&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Let's inspect what we got back.&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #007800;"&gt;$?&lt;/span&gt; &lt;span style="color: #660033;"&gt;-ne&lt;/span&gt; &lt;span style="color: #000000;"&gt;0&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"describe-security-groups failed with code $?"&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;exit&lt;/span&gt; &lt;span style="color: #007800;"&gt;$?&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;# If we didn't get a security group then create&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #660033;"&gt;-z&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$SECURITY&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
	&lt;span style="color: #007800;"&gt;SECURITY&lt;/span&gt;=&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;aws ec2 create-security-group \
		&lt;span style="color: #660033;"&gt;--description&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"Ingress Port 80 Anywhere"&lt;/span&gt; \
		&lt;span style="color: #660033;"&gt;--group-name&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"Fargate Webserver Port 80"&lt;/span&gt; \
		&lt;span style="color: #660033;"&gt;--vpc-id&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$VPC&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; jq .GroupId &lt;span style="color: #660033;"&gt;-r&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;
 
 
	aws ec2 authorize-security-group-ingress \
		&lt;span style="color: #660033;"&gt;--group-id&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$SECURITY&lt;/span&gt;"&lt;/span&gt; \
		&lt;span style="color: #660033;"&gt;--ip-permissions&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"FromPort=80,ToPort=80,IpProtocol=TCP,IpRanges=[{CidrIp=0.0.0.0/0}]"&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Run the Fargate Task&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;Next I run the Fargate task. This is the sample Fargate task covered in the AWS documentation and uses the httpd docker image. When I created it in the console I called it "first-run-task-definition" - for the life of me I can't remember why I chose such a crazy name! Note I am piping the result through jq as per normal and then onwards through sed to get the task id without all the arn information that precedes it. The sed command looks for the final forward slash in the task arn and crops anything before it. 
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #666666; font-style: italic;"&gt;# Run the task and parse the task ARN for polling later to determine its status&lt;/span&gt;
&lt;span style="color: #007800;"&gt;TASK&lt;/span&gt;=&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;aws ecs run-task \
	&lt;span style="color: #660033;"&gt;--cluster&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"default"&lt;/span&gt; \
	&lt;span style="color: #660033;"&gt;--task-definition&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"first-run-task-definition"&lt;/span&gt; \
	&lt;span style="color: #660033;"&gt;--network-configuration&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"awsvpcConfiguration={subnets=[&lt;span style="color: #007800;"&gt;${SUBNET}&lt;/span&gt;],securityGroups=[&lt;span style="color: #007800;"&gt;${SECURITY}&lt;/span&gt;],assignPublicIp=ENABLED}"&lt;/span&gt; \
	&lt;span style="color: #660033;"&gt;--launch-type&lt;/span&gt; FARGATE  &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; jq .tasks&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #000000;"&gt;0&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;.taskArn &lt;span style="color: #660033;"&gt;-r&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;sed&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"s/.*\///"&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Let's inspect what we got back. There should be a task identifier.&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #007800;"&gt;$?&lt;/span&gt; &lt;span style="color: #660033;"&gt;-ne&lt;/span&gt; &lt;span style="color: #000000;"&gt;0&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"task-run failed with code $?"&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;exit&lt;/span&gt; &lt;span style="color: #007800;"&gt;$?&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;
 
&lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #660033;"&gt;-z&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$TASK&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"task-run could not create task"&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;exit&lt;/span&gt; &lt;span style="color: #000000;"&gt;1&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Loop and Wait for Fargate Task to get to RUNNING Status&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;Next I have to wait for the task to acquire RUNNING status, However I can't wait for ever, and thus I have wrapped a shell script rule into a timeout mechanism. I have allowed for 5 minutes for the task to get to RUNNING status and that should be more than enough.
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #666666; font-style: italic;"&gt;# Loop around until we see a RUNNING status or timeout after 10 x 30 second sleeps&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;for&lt;/span&gt; i &lt;span style="color: #000000; font-weight: bold;"&gt;in&lt;/span&gt; &lt;span style="color: #000000;"&gt;1&lt;/span&gt; &lt;span style="color: #000000;"&gt;2&lt;/span&gt; &lt;span style="color: #000000;"&gt;3&lt;/span&gt; &lt;span style="color: #000000;"&gt;4&lt;/span&gt; &lt;span style="color: #000000;"&gt;5&lt;/span&gt; &lt;span style="color: #000000;"&gt;6&lt;/span&gt; &lt;span style="color: #000000;"&gt;7&lt;/span&gt; &lt;span style="color: #000000;"&gt;8&lt;/span&gt; &lt;span style="color: #000000;"&gt;9&lt;/span&gt; &lt;span style="color: #000000;"&gt;10&lt;/span&gt; &lt;span style="color: #000000;"&gt;11&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;do&lt;/span&gt;
	&lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #007800;"&gt;$i&lt;/span&gt; &lt;span style="color: #660033;"&gt;-eq&lt;/span&gt; &lt;span style="color: #000000;"&gt;11&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
		&lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"Timed out before could establish task is running"&lt;/span&gt;
		&lt;span style="color: #7a0874; font-weight: bold;"&gt;exit&lt;/span&gt; &lt;span style="color: #000000;"&gt;1&lt;/span&gt;
	&lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;
 
	&lt;span style="color: #007800;"&gt;STATUS&lt;/span&gt;=&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;aws ecs describe-tasks &lt;span style="color: #660033;"&gt;--cluster&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;"default"&lt;/span&gt; &lt;span style="color: #660033;"&gt;--tasks&lt;/span&gt; &lt;span style="color: #007800;"&gt;$TASK&lt;/span&gt;  &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; jq .tasks&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #000000;"&gt;0&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;.lastStatus -r&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;
 
	&lt;span style="color: #666666; font-style: italic;"&gt;# Did it exit unexpectedly?&lt;/span&gt;
	&lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #007800;"&gt;$?&lt;/span&gt; &lt;span style="color: #660033;"&gt;-ne&lt;/span&gt; &lt;span style="color: #000000;"&gt;0&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
		&lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"describe-tasks failed with code $?"&lt;/span&gt;
		&lt;span style="color: #7a0874; font-weight: bold;"&gt;exit&lt;/span&gt; &lt;span style="color: #007800;"&gt;$?&lt;/span&gt;
	&lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;
 
	&lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$STATUS&lt;/span&gt;"&lt;/span&gt; = &lt;span style="color: #ff0000;"&gt;"RUNNING"&lt;/span&gt;  &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
		&lt;span style="color: #7a0874; font-weight: bold;"&gt;break&lt;/span&gt;
	&lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;
 
	&lt;span style="color: #c20cb9; font-weight: bold;"&gt;sleep&lt;/span&gt; &lt;span style="color: #000000;"&gt;30&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;done&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Obtain the Network Interface Id&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;The ENI is available in the Fargate task's description so I needed to parse this on my quest to get the public IP. 
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #666666; font-style: italic;"&gt;# Get the network Interface id&lt;/span&gt;
&lt;span style="color: #007800;"&gt;ENI&lt;/span&gt;=&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;aws ecs describe-tasks &lt;span style="color: #660033;"&gt;--cluster&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;"default"&lt;/span&gt; &lt;span style="color: #660033;"&gt;--tasks&lt;/span&gt; &lt;span style="color: #007800;"&gt;$TASK&lt;/span&gt;  &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; jq &lt;span style="color: #ff0000;"&gt;'.tasks[0].attachments[0].details[] | select(.name == "networkInterfaceId") | .value'&lt;/span&gt; &lt;span style="color: #660033;"&gt;-r&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Let's inspect what we got back. There should be a network interface id.&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #007800;"&gt;$?&lt;/span&gt; &lt;span style="color: #660033;"&gt;-ne&lt;/span&gt; &lt;span style="color: #000000;"&gt;0&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"describe-tasks failed with code $?"&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;exit&lt;/span&gt; &lt;span style="color: #007800;"&gt;$?&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;
 
&lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #660033;"&gt;-z&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$ENI&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"describe-tasks could not establish eni"&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;exit&lt;/span&gt; &lt;span style="color: #000000;"&gt;1&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Get the Public IP Address&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;With the ENI it is possible to parse the the descriptions of all the network interfaces for the public IP address. 
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #007800;"&gt;PUBLIC_IP&lt;/span&gt;=&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;aws ec2 describe-network-interfaces &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; jq &lt;span style="color: #660033;"&gt;--arg&lt;/span&gt; ENI &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$ENI&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;'.NetworkInterfaces[] | select(.NetworkInterfaceId == $ENI) | .PrivateIpAddresses[0].Association.PublicIp'&lt;/span&gt; -r&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Did we get an IP address?&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #007800;"&gt;$?&lt;/span&gt; &lt;span style="color: #660033;"&gt;-ne&lt;/span&gt; &lt;span style="color: #000000;"&gt;0&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"describe-network-interfaces failed with code $?"&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;exit&lt;/span&gt; &lt;span style="color: #007800;"&gt;$?&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;
 
&lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #660033;"&gt;-z&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$PUBLIC_IP&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"describe-network-interfaces could not retrieve public IP address"&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;exit&lt;/span&gt; &lt;span style="color: #000000;"&gt;1&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Get the Parent Domain's Hosted Zone Id&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;The shell script needs to know about the parent domain and the subdomain name (which in my case is a feature branch name) - so those need to be retrieved from runtime arguments. This will go at the top of the shell script.
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #660033;"&gt;-z&lt;/span&gt; &lt;span style="color: #007800;"&gt;$1&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;||&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #660033;"&gt;-z&lt;/span&gt; &lt;span style="color: #007800;"&gt;$2&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"usage: parent_domain_name feature_branch_name"&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;exit&lt;/span&gt; &lt;span style="color: #000000;"&gt;1&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;
 
&lt;span style="color: #007800;"&gt;BRANCH&lt;/span&gt;=&lt;span style="color: #007800;"&gt;$2&lt;/span&gt;.&lt;span style="color: #007800;"&gt;$1&lt;/span&gt;
&lt;span style="color: #007800;"&gt;PARENT&lt;/span&gt;=&lt;span style="color: #007800;"&gt;$1&lt;/span&gt;.&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
Then continuing at the end of the codebase, the following gets the parent domain
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #007800;"&gt;PARENT_ZONE&lt;/span&gt;=&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;aws route53 list-hosted-zones-by-name &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; jq &lt;span style="color: #660033;"&gt;--arg&lt;/span&gt; PARENT &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$PARENT&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;'.HostedZones[] | select(.Name == $PARENT) | .Id'&lt;/span&gt; &lt;span style="color: #660033;"&gt;-r&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;sed&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"s/.*\///"&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Add the Feature Branch Name and Public IP Address to the Parent Hosted Zone&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;Now I created a new record set for the parent domain's hosted zone. This uses the AWS CLI command change-resource-record-sets which allows for insert, upsert and delete. I needed a DNS A record adding. The easiest way of providing the runtime parameters is via a JSON structure and that is created in shell script heredoc format to simplify shell script escaping. 
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #007800;"&gt;BATCH&lt;/span&gt;=$&lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;cat&lt;/span&gt; &lt;span style="color: #cc0000; font-style: italic;"&gt;&lt;&lt;EOT
{
  "Comment":"CREATE/DELETE/UPSERT a record",
  "Changes":[{
    "Action": "UPSERT",
    		  "ResourceRecordSet": {
    		  	"Name": "${BRANCH}",
    		  	"Type": "A",
    		  	"TTL": 300,
    		  	"ResourceRecords": [{ "Value": "${PUBLIC_IP}"}]
    		  }
  }]
}
EOT&lt;/span&gt;
&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;
 
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Use the hosted zone of the tld&lt;/span&gt;
aws route53 change-resource-record-sets \
	&lt;span style="color: #660033;"&gt;--hosted-zone-id&lt;/span&gt; &lt;span style="color: #007800;"&gt;$PARENT_ZONE&lt;/span&gt; \
	&lt;span style="color: #660033;"&gt;--change-batch&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$BATCH&lt;/span&gt;"&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Create the Feature Branch Hosted Zone&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;The final AWS CLI call is to use create-hosted-zone, and here I needed to provide the feature branch name and an arbitrary unique caller reference for which I used a timestamp. 
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #007800;"&gt;timestamp&lt;/span&gt;=$&lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;date&lt;/span&gt; +&lt;span style="color: #000000; font-weight: bold;"&gt;%&lt;/span&gt;s&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Now create a new hosted zone of the feature branch&lt;/span&gt;
aws route53 create-hosted-zone \
	&lt;span style="color: #660033;"&gt;--name&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$BRANCH&lt;/span&gt;"&lt;/span&gt; \
	&lt;span style="color: #660033;"&gt;--caller-reference&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$timestamp&lt;/span&gt;"&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;The Complete Script&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;The complete script is listed below. Note that for brevity and easy reading I have cut a few coding standards. There is repetition in the error condition checking. This should be rewritten with calls to shell script functions in a separate file. 
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #666666; font-style: italic;"&gt;#!/bin/bash&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Script to assign a public IP address issued by a Fargate task to a subdomain&lt;/span&gt;
 
&lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #660033;"&gt;-z&lt;/span&gt; &lt;span style="color: #007800;"&gt;$1&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;||&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #660033;"&gt;-z&lt;/span&gt; &lt;span style="color: #007800;"&gt;$2&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"usage: parent_domain_name feature_branch_name"&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;exit&lt;/span&gt; &lt;span style="color: #000000;"&gt;1&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;
 
&lt;span style="color: #007800;"&gt;BRANCH&lt;/span&gt;=&lt;span style="color: #007800;"&gt;$2&lt;/span&gt;.&lt;span style="color: #007800;"&gt;$1&lt;/span&gt;
&lt;span style="color: #007800;"&gt;PARENT&lt;/span&gt;=&lt;span style="color: #007800;"&gt;$1&lt;/span&gt;.
 
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Get the default VPC.&lt;/span&gt;
&lt;span style="color: #007800;"&gt;VPC&lt;/span&gt;=&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;aws ec2 describe-vpcs &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; jq &lt;span style="color: #ff0000;"&gt;'.Vpcs[] | select(.IsDefault == true) | .VpcId'&lt;/span&gt; -r&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Get the first subnet of the VPC&lt;/span&gt;
&lt;span style="color: #007800;"&gt;SUBNET&lt;/span&gt;=&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;aws ec2 describe-subnets &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; jq &lt;span style="color: #660033;"&gt;--arg&lt;/span&gt; VPC &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$VPC&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;'.Subnets[] | select(.VpcId == $VPC) | .SubnetId'&lt;/span&gt; &lt;span style="color: #660033;"&gt;-r&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;head&lt;/span&gt; &lt;span style="color: #660033;"&gt;-n&lt;/span&gt; &lt;span style="color: #000000;"&gt;1&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Check if our security group for port 80 webserver already exists. Search for our funky unique description&lt;/span&gt;
&lt;span style="color: #007800;"&gt;SECURITY&lt;/span&gt;=&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;aws ec2 describe-security-groups &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; jq &lt;span style="color: #ff0000;"&gt;' .SecurityGroups[] | select (.Description == "Ingress Port 80 Anywhere") | .GroupId'&lt;/span&gt; -r&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Let's inspect what we got back.&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #007800;"&gt;$?&lt;/span&gt; &lt;span style="color: #660033;"&gt;-ne&lt;/span&gt; &lt;span style="color: #000000;"&gt;0&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"describe-security-groups failed with code $?"&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;exit&lt;/span&gt; &lt;span style="color: #007800;"&gt;$?&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;# If we didn't get a security group then create&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$SECURITY&lt;/span&gt;"&lt;/span&gt; = &lt;span style="color: #ff0000;"&gt;""&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
	&lt;span style="color: #007800;"&gt;SECURITY&lt;/span&gt;=&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;aws ec2 create-security-group \
		&lt;span style="color: #660033;"&gt;--description&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"Ingress Port 80 Anywhere"&lt;/span&gt; \
		&lt;span style="color: #660033;"&gt;--group-name&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"Fargate Webserver Port 80"&lt;/span&gt; \
		&lt;span style="color: #660033;"&gt;--vpc-id&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$VPC&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; jq .GroupId &lt;span style="color: #660033;"&gt;-r&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;
 
 
	aws ec2 authorize-security-group-ingress \
		&lt;span style="color: #660033;"&gt;--group-id&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$SECURITY&lt;/span&gt;"&lt;/span&gt; \
		&lt;span style="color: #660033;"&gt;--ip-permissions&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"FromPort=80,ToPort=80,IpProtocol=TCP,IpRanges=[{CidrIp=0.0.0.0/0}]"&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Run the task and parse the task ARN for polling later to determine its status&lt;/span&gt;
&lt;span style="color: #007800;"&gt;TASK&lt;/span&gt;=&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;aws ecs run-task \
	&lt;span style="color: #660033;"&gt;--cluster&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"default"&lt;/span&gt; \
	&lt;span style="color: #660033;"&gt;--task-definition&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"first-run-task-definition"&lt;/span&gt; \
	&lt;span style="color: #660033;"&gt;--network-configuration&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"awsvpcConfiguration={subnets=[&lt;span style="color: #007800;"&gt;${SUBNET}&lt;/span&gt;],securityGroups=[&lt;span style="color: #007800;"&gt;${SECURITY}&lt;/span&gt;],assignPublicIp=ENABLED}"&lt;/span&gt; \
	&lt;span style="color: #660033;"&gt;--launch-type&lt;/span&gt; FARGATE  &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; jq .tasks&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #000000;"&gt;0&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;.taskArn &lt;span style="color: #660033;"&gt;-r&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;sed&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"s/.*\///"&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Let's inspect what we got back. There should be a task identifier.&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #007800;"&gt;$?&lt;/span&gt; &lt;span style="color: #660033;"&gt;-ne&lt;/span&gt; &lt;span style="color: #000000;"&gt;0&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"task-run failed with code $?"&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;exit&lt;/span&gt; &lt;span style="color: #007800;"&gt;$?&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;
 
&lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #660033;"&gt;-z&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$TASK&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"task-run could not create task"&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;exit&lt;/span&gt; &lt;span style="color: #000000;"&gt;1&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Loop around until we see a RUNNING status or timeout after 10 x 30 second sleeps&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;for&lt;/span&gt; i &lt;span style="color: #000000; font-weight: bold;"&gt;in&lt;/span&gt; &lt;span style="color: #000000;"&gt;1&lt;/span&gt; &lt;span style="color: #000000;"&gt;2&lt;/span&gt; &lt;span style="color: #000000;"&gt;3&lt;/span&gt; &lt;span style="color: #000000;"&gt;4&lt;/span&gt; &lt;span style="color: #000000;"&gt;5&lt;/span&gt; &lt;span style="color: #000000;"&gt;6&lt;/span&gt; &lt;span style="color: #000000;"&gt;7&lt;/span&gt; &lt;span style="color: #000000;"&gt;8&lt;/span&gt; &lt;span style="color: #000000;"&gt;9&lt;/span&gt; &lt;span style="color: #000000;"&gt;10&lt;/span&gt; &lt;span style="color: #000000;"&gt;11&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;do&lt;/span&gt;
	&lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #007800;"&gt;$i&lt;/span&gt; &lt;span style="color: #660033;"&gt;-eq&lt;/span&gt; &lt;span style="color: #000000;"&gt;11&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
		&lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"Timed out before could establish task is running"&lt;/span&gt;
		&lt;span style="color: #7a0874; font-weight: bold;"&gt;exit&lt;/span&gt; &lt;span style="color: #000000;"&gt;1&lt;/span&gt;
	&lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;
 
	&lt;span style="color: #007800;"&gt;STATUS&lt;/span&gt;=&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;aws ecs describe-tasks &lt;span style="color: #660033;"&gt;--cluster&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;"default"&lt;/span&gt; &lt;span style="color: #660033;"&gt;--tasks&lt;/span&gt; &lt;span style="color: #007800;"&gt;$TASK&lt;/span&gt;  &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; jq .tasks&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #000000;"&gt;0&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;.lastStatus -r&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;
 
	&lt;span style="color: #666666; font-style: italic;"&gt;# Did it exit unexpectedly?&lt;/span&gt;
	&lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #007800;"&gt;$?&lt;/span&gt; &lt;span style="color: #660033;"&gt;-ne&lt;/span&gt; &lt;span style="color: #000000;"&gt;0&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
		&lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"describe-tasks failed with code $?"&lt;/span&gt;
		&lt;span style="color: #7a0874; font-weight: bold;"&gt;exit&lt;/span&gt; &lt;span style="color: #007800;"&gt;$?&lt;/span&gt;
	&lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;
 
	&lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$STATUS&lt;/span&gt;"&lt;/span&gt; = &lt;span style="color: #ff0000;"&gt;"RUNNING"&lt;/span&gt;  &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
		&lt;span style="color: #7a0874; font-weight: bold;"&gt;break&lt;/span&gt;
	&lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;
 
	&lt;span style="color: #c20cb9; font-weight: bold;"&gt;sleep&lt;/span&gt; &lt;span style="color: #000000;"&gt;30&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;done&lt;/span&gt;
 
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Get the network Interface id&lt;/span&gt;
&lt;span style="color: #007800;"&gt;ENI&lt;/span&gt;=&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;aws ecs describe-tasks &lt;span style="color: #660033;"&gt;--cluster&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;"default"&lt;/span&gt; &lt;span style="color: #660033;"&gt;--tasks&lt;/span&gt; &lt;span style="color: #007800;"&gt;$TASK&lt;/span&gt;  &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; jq &lt;span style="color: #ff0000;"&gt;'.tasks[0].attachments[0].details[] | select(.name == "networkInterfaceId") | .value'&lt;/span&gt; &lt;span style="color: #660033;"&gt;-r&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Let's inspect what we got back. There should be a network interface id.&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #007800;"&gt;$?&lt;/span&gt; &lt;span style="color: #660033;"&gt;-ne&lt;/span&gt; &lt;span style="color: #000000;"&gt;0&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"describe-tasks failed with code $?"&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;exit&lt;/span&gt; &lt;span style="color: #007800;"&gt;$?&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;
 
&lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #660033;"&gt;-z&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$ENI&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"describe-tasks could not establish eni"&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;exit&lt;/span&gt; &lt;span style="color: #000000;"&gt;1&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;
 
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Get the Public IP Address&lt;/span&gt;
&lt;span style="color: #007800;"&gt;PUBLIC_IP&lt;/span&gt;=&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;aws ec2 describe-network-interfaces &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; jq &lt;span style="color: #660033;"&gt;--arg&lt;/span&gt; ENI &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$ENI&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;'.NetworkInterfaces[] | select(.NetworkInterfaceId == $ENI) | .PrivateIpAddresses[0].Association.PublicIp'&lt;/span&gt; -r&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Did we get an IP address?&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #007800;"&gt;$?&lt;/span&gt; &lt;span style="color: #660033;"&gt;-ne&lt;/span&gt; &lt;span style="color: #000000;"&gt;0&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"describe-network-interfaces failed with code $?"&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;exit&lt;/span&gt; &lt;span style="color: #007800;"&gt;$?&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;
 
&lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt; &lt;span style="color: #660033;"&gt;-z&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$PUBLIC_IP&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;; &lt;span style="color: #000000; font-weight: bold;"&gt;then&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;echo&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"describe-network-interfaces could not retrieve public IP address"&lt;/span&gt;
	&lt;span style="color: #7a0874; font-weight: bold;"&gt;exit&lt;/span&gt; &lt;span style="color: #000000;"&gt;1&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;fi&lt;/span&gt;
 
&lt;span style="color: #007800;"&gt;BATCH&lt;/span&gt;=$&lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;cat&lt;/span&gt; &lt;span style="color: #cc0000; font-style: italic;"&gt;&lt;&lt;EOT
{
  "Comment":"CREATE/DELETE/UPSERT a record",
  "Changes":[{
    "Action": "UPSERT",
    		  "ResourceRecordSet": {
    		  	"Name": "${BRANCH}",
    		  	"Type": "A",
    		  	"TTL": 300,
    		  	"ResourceRecords": [{ "Value": "${PUBLIC_IP}"}]
    		  }
  }]
}
EOT&lt;/span&gt;
&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;
 
&lt;span style="color: #007800;"&gt;PARENT_ZONE&lt;/span&gt;=&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;aws route53 list-hosted-zones-by-name &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; jq &lt;span style="color: #660033;"&gt;--arg&lt;/span&gt; PARENT &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$PARENT&lt;/span&gt;"&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;'.HostedZones[] | select(.Name == $PARENT) | .Id'&lt;/span&gt; &lt;span style="color: #660033;"&gt;-r&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;sed&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"s/.*\///"&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;
 
aws route53 change-resource-record-sets \
	&lt;span style="color: #660033;"&gt;--hosted-zone-id&lt;/span&gt; &lt;span style="color: #007800;"&gt;$PARENT_ZONE&lt;/span&gt; \
	&lt;span style="color: #660033;"&gt;--change-batch&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$BATCH&lt;/span&gt;"&lt;/span&gt;
 
 
&lt;span style="color: #007800;"&gt;timestamp&lt;/span&gt;=$&lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;date&lt;/span&gt; +&lt;span style="color: #000000; font-weight: bold;"&gt;%&lt;/span&gt;s&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;
 
&lt;span style="color: #666666; font-style: italic;"&gt;# Now create a new hosted zone of the feature branch&lt;/span&gt;
aws route53 create-hosted-zone \
	&lt;span style="color: #660033;"&gt;--name&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$BRANCH&lt;/span&gt;"&lt;/span&gt; \
	&lt;span style="color: #660033;"&gt;--caller-reference&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;"&lt;span style="color: #007800;"&gt;$timestamp&lt;/span&gt;"&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Invoking the Script&lt;/div&gt;
      
      &lt;div class="field field--name-field-blog-image field--type-image field--label-hidden field--items"&gt;
              &lt;div class="field--item"&gt;    &lt;img srcset="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2019-11/Screenshot_2019-11-03_at_11_25_07-edited1.png?itok=6zDl28OV 325w, https://assets.badzilla.co.uk/s3fs-public/styles/max_650x650/public/2019-11/Screenshot_2019-11-03_at_11_25_07-edited1.png?itok=PtA97zAh 650w, https://assets.badzilla.co.uk/s3fs-public/styles/max_1300x1300/public/2019-11/Screenshot_2019-11-03_at_11_25_07-edited1.png?itok=onEwER9j 1300w, https://assets.badzilla.co.uk/s3fs-public/styles/max_2600x2600/public/2019-11/Screenshot_2019-11-03_at_11_25_07-edited1.png?itok=3pXhsRib 1362w" sizes="(min-width: 1290px) 1290px, 100vw" src="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2019-11/Screenshot_2019-11-03_at_11_25_07-edited1.png?itok=6zDl28OV" alt="Full Domain Name" typeof="foaf:Image" class="img-responsive" /&gt;


&lt;/div&gt;
          &lt;/div&gt;
  
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;The script requires two parameters as previous discussed. Here's my example for the blog:
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #666666;"&gt;$ &lt;/span&gt;.&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;feature-branch.sh saasidate.com feature--doi-&lt;span style="color: #000000;"&gt;746&lt;/span&gt;-my-whizzy-new-feature&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
Currently the output of the script is the response from the AWS CLI route53 create-hosted-zone call, and here you can detect the full domain name.&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Checking the Outcome&lt;/div&gt;
      
      &lt;div class="field field--name-field-blog-image field--type-image field--label-hidden field--items"&gt;
              &lt;div class="field--item"&gt;    &lt;img srcset="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2019-11/Screenshot%202019-11-03%20at%2011.58.11.png?itok=J7vAfmhk 325w, https://assets.badzilla.co.uk/s3fs-public/styles/max_650x650/public/2019-11/Screenshot%202019-11-03%20at%2011.58.11.png?itok=UyDrsDoT 650w, https://assets.badzilla.co.uk/s3fs-public/styles/max_1300x1300/public/2019-11/Screenshot%202019-11-03%20at%2011.58.11.png?itok=vqKiRvSi 1300w, https://assets.badzilla.co.uk/s3fs-public/styles/max_2600x2600/public/2019-11/Screenshot%202019-11-03%20at%2011.58.11.png?itok=YUAatBcF 2600w" sizes="(min-width: 1290px) 1290px, 100vw" src="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2019-11/Screenshot%202019-11-03%20at%2011.58.11.png?itok=J7vAfmhk" alt="Tasks Running" typeof="foaf:Image" class="img-responsive" /&gt;


&lt;/div&gt;
              &lt;div class="field--item"&gt;    &lt;img srcset="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2019-11/Screenshot%202019-11-03%20at%2012.00.56.png?itok=d-SSfTq- 325w, https://assets.badzilla.co.uk/s3fs-public/styles/max_650x650/public/2019-11/Screenshot%202019-11-03%20at%2012.00.56.png?itok=N4C40cpp 650w, https://assets.badzilla.co.uk/s3fs-public/styles/max_1300x1300/public/2019-11/Screenshot%202019-11-03%20at%2012.00.56.png?itok=oHvt2vUZ 1300w, https://assets.badzilla.co.uk/s3fs-public/styles/max_2600x2600/public/2019-11/Screenshot%202019-11-03%20at%2012.00.56.png?itok=wa9icCup 2254w" sizes="(min-width: 1290px) 1290px, 100vw" src="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2019-11/Screenshot%202019-11-03%20at%2012.00.56.png?itok=d-SSfTq-" alt="Route 53" typeof="foaf:Image" class="img-responsive" /&gt;


&lt;/div&gt;
          &lt;/div&gt;
  
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;&lt;p&gt;Obviously the first check is to copy and paste the url of the feature branch into a browser and see if it loads. An example of this is the blog heading image at the top of the page. &lt;/p&gt;

&lt;p&gt;Also the AWS console is the place to check everything is as required. Navigate to ECS -&gt; default -&gt; Tasks and you should see a screenshot similar to the first one immediately above. This is the task we invoked from inside our shell script. Now navigate to Route 53 -&gt; Hosted Zones -&gt; {domain name} and you can see the feature branch and its IP address.&lt;/p&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Steps left to do&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;&lt;p&gt;New hosted zones will normally propagate in 60 seconds in Route 53 - but it would be good if the script above polls Route 53 every 10 seconds or so and reports back the subdomain url and the IP address once the propagation has completed. This should be surfaced on the command line as a minimum, but perhaps a notification on Slack would be even better. Both options are trivial. &lt;/p&gt;

&lt;p&gt;Whilst the idea is that the Fargate tasks should persist, they shouldn't be around forever. Therefore there needs to be clear up activities to remove the feature subdomain from the parent domain's hosted zone, and the subdomain hosted zone. Also there obviously needs a step to stop the Fargate task. &lt;/p&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Caveats&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;&lt;p&gt;There are caveats to this solution - but for my use case, it's one of those rare occurrences in life that the caveats don't apply to me. &lt;/p&gt;

&lt;p&gt;Firstly, this solution will only work with a Fargate &lt;strong&gt;task&lt;/strong&gt; and not an ECS &lt;strong&gt;service&lt;/strong&gt; running a Fargate task. Tasks should be run as services for production environments since services give you great things like replication, and health percentages against number of running tasks. There is therefore no scaling, no load balancing, no DDOS protection in what I'm offering here.&lt;/p&gt;

&lt;p&gt;Fargate tasks run in isolation are perfect for spun up short living environments such as playgrounds for devs and QAs to run manual tests against or troubleshoot development issues - which is exactly my use case. &lt;/p&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
          &lt;/div&gt;
  
      &lt;div class="field field--name-field-blog-youtube field--type-entity-reference-revisions field--label-hidden field--items"&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-text-youtube paragraph--view-mode--default"&gt;
          
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-text-youtube paragraph--view-mode--default"&gt;
          
      &lt;/div&gt;
&lt;/div&gt;
          &lt;/div&gt;
  
  &lt;div class="field field--name-field-blog-terms field--type-entity-reference field--label-inline"&gt;
    &lt;div class="field--label"&gt;blog terms&lt;/div&gt;
          &lt;span class="field__items"&gt;
              &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/aws" hreflang="en"&gt;AWS&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/awscli" hreflang="en"&gt;AWS CLI&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/docker" hreflang="en"&gt;Docker&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/devops" hreflang="en"&gt;devops&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/fargate" hreflang="en"&gt;Fargate&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/ecs" hreflang="en"&gt;ECS&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/development" hreflang="en"&gt;Development&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/Route53" hreflang="en"&gt;Route 53&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/bash" hreflang="en"&gt;bash&lt;/a&gt;&lt;/span&gt;
              &lt;/span&gt;
      &lt;/div&gt;
</description>
  <pubDate>Fri, 01 Nov 2019 15:03:02 +0000</pubDate>
    <dc:creator>nigel</dc:creator>
    <guid isPermaLink="false">171 at http://badzilla.co.uk</guid>
    </item>
<item>
  <title>Drupal 8 and DRUD Tech's ddev Local Development Environment</title>
  <link>http://badzilla.co.uk/drupal-8-and-drud-techs-ddev-local-development-environment</link>
  <description>
&lt;span&gt;Drupal 8 and DRUD Tech's ddev Local Development Environment&lt;/span&gt;

&lt;span&gt;&lt;span lang="" about="http://badzilla.co.uk/user/1" typeof="schema:Person" property="schema:name" datatype="" xml:lang=""&gt;nigel&lt;/span&gt;&lt;/span&gt;

&lt;span&gt;Sat, 10/03/2018 - 21:12&lt;/span&gt;

      &lt;div class="field field--name-field-heading-image-text field--type-entity-reference-revisions field--label-hidden field--items"&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
      &lt;div class="field field--name-field-blog-image field--type-image field--label-hidden field--items"&gt;
              &lt;div class="field--item"&gt;    &lt;img srcset="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2018-03/Screen%20Shot%202018-03-11%20at%2010.40.36.png?itok=RMPUTXj1 325w, https://assets.badzilla.co.uk/s3fs-public/styles/max_650x650/public/2018-03/Screen%20Shot%202018-03-11%20at%2010.40.36.png?itok=Z0gmcixg 650w, https://assets.badzilla.co.uk/s3fs-public/styles/max_1300x1300/public/2018-03/Screen%20Shot%202018-03-11%20at%2010.40.36.png?itok=JHQH5DPa 1300w, https://assets.badzilla.co.uk/s3fs-public/styles/max_2600x2600/public/2018-03/Screen%20Shot%202018-03-11%20at%2010.40.36.png?itok=IN5xeixh 2294w" sizes="(min-width: 1290px) 1290px, 100vw" src="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2018-03/Screen%20Shot%202018-03-11%20at%2010.40.36.png?itok=RMPUTXj1" alt="Command Line" typeof="foaf:Image" class="img-responsive" /&gt;


&lt;/div&gt;
          &lt;/div&gt;
  
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;&lt;p&gt;My favourite presentation at DrupalCamp London 2018 was &lt;strong&gt;Turbocharge Your Agency&lt;/strong&gt; given by DRUD Tech co-founder Kevin Bridges and Jeffrey A. "jam" McGuire. They talked at length about the container solution &lt;strong&gt;ddev&lt;/strong&gt; which enables developers to manage their local environments and thus optimise their time and in addition save their configuration under source control. Furthermore the demonstration showed that it was possible to flip between different configurations with different Drupal versions easily and quickly. The solution found &lt;a href="https://github.com/drud/ddev"&gt;here&lt;/a&gt; uses Docker and is wrapped by the lightning fast Golang.&lt;/p&gt;
&lt;p&gt;I've been thinking for a while about moving from my existing hand crafted Virtual Machine towards Docker. My VM's configuration isn't under source control management, and has built up over the years into quite a complex beast. I have Jenkins, phing, composer, Drupal console, Mail Catcher, Compass, node, npm, Python, nginx, Apache, MariaDB and MongoDB that I can remember off the top of my head. It's becoming a difficult proposition to keep it all working. When I need to run a different version of PHP I manually switch simlinks around. Oh for something easier. &lt;/p&gt;
&lt;p&gt;So I elected to investigate whether Drud Tech's offering could possibly help out. The demonstration given by their guys at DrupalCamp London 2018 showed the ease of moving between D7 and D8 repos. However they were fresh builds and for the tool to be of value to me, it would have to work from pre-existing codebases. &lt;/p&gt;
&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Installing a VirtualBox VM&lt;/div&gt;
      
      &lt;div class="field field--name-field-blog-image field--type-image field--label-hidden field--items"&gt;
              &lt;div class="field--item"&gt;    &lt;img srcset="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2018-03/Screen%20Shot%202018-03-05%20at%2021.41.04.png?itok=YLavAD3q 325w, https://assets.badzilla.co.uk/s3fs-public/styles/max_650x650/public/2018-03/Screen%20Shot%202018-03-05%20at%2021.41.04.png?itok=p9TxKiLl 650w, https://assets.badzilla.co.uk/s3fs-public/styles/max_1300x1300/public/2018-03/Screen%20Shot%202018-03-05%20at%2021.41.04.png?itok=kWThqz1Q 1300w, https://assets.badzilla.co.uk/s3fs-public/styles/max_2600x2600/public/2018-03/Screen%20Shot%202018-03-05%20at%2021.41.04.png?itok=GhAKBne5 1764w" sizes="(min-width: 1290px) 1290px, 100vw" src="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2018-03/Screen%20Shot%202018-03-05%20at%2021.41.04.png?itok=YLavAD3q" alt="ddev VM" typeof="foaf:Image" class="img-responsive" /&gt;


&lt;/div&gt;
              &lt;div class="field--item"&gt;    &lt;img srcset="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2018-03/Screen%20Shot%202018-03-05%20at%2022.01.38.png?itok=fR6uv1yE 325w, https://assets.badzilla.co.uk/s3fs-public/styles/max_650x650/public/2018-03/Screen%20Shot%202018-03-05%20at%2022.01.38.png?itok=5GkmA5Mt 650w, https://assets.badzilla.co.uk/s3fs-public/styles/max_1300x1300/public/2018-03/Screen%20Shot%202018-03-05%20at%2022.01.38.png?itok=oYLUJWwI 1300w, https://assets.badzilla.co.uk/s3fs-public/styles/max_2600x2600/public/2018-03/Screen%20Shot%202018-03-05%20at%2022.01.38.png?itok=FgT36KcJ 1768w" sizes="(min-width: 1290px) 1290px, 100vw" src="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2018-03/Screen%20Shot%202018-03-05%20at%2022.01.38.png?itok=fR6uv1yE" alt="ifconfig" typeof="foaf:Image" class="img-responsive" /&gt;


&lt;/div&gt;
              &lt;div class="field--item"&gt;    &lt;img srcset="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2018-03/Screen%20Shot%202018-03-05%20at%2022.06.05.png?itok=4NUDSvv6 325w, https://assets.badzilla.co.uk/s3fs-public/styles/max_650x650/public/2018-03/Screen%20Shot%202018-03-05%20at%2022.06.05.png?itok=QwIRA5Ls 650w, https://assets.badzilla.co.uk/s3fs-public/styles/max_1300x1300/public/2018-03/Screen%20Shot%202018-03-05%20at%2022.06.05.png?itok=J1ySsudd 1300w, https://assets.badzilla.co.uk/s3fs-public/styles/max_2600x2600/public/2018-03/Screen%20Shot%202018-03-05%20at%2022.06.05.png?itok=quF2Q4GI 1526w" sizes="(min-width: 1290px) 1290px, 100vw" src="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2018-03/Screen%20Shot%202018-03-05%20at%2022.06.05.png?itok=4NUDSvv6" alt="ssh port forward" typeof="foaf:Image" class="img-responsive" /&gt;


&lt;/div&gt;
          &lt;/div&gt;
  
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;&lt;p&gt;This was purely a Proof of Concept so as a consequence I needed to keep anything I did in a ring-fenced environment. Therefore a VirtualBox Ubuntu 16.04LTS image was used as a starting point. I won't provide screenshots of the entire build process since I have previous blogs to cover this. &lt;/p&gt;

&lt;p&gt;Once the build has completed and I have logged in I issue a &lt;em&gt;ifconfig&lt;/em&gt; command to determine the IP address which is 10.0.2.15 (second screenshot). This will need to be used with the network configuration. &lt;/p&gt;

&lt;p&gt;When I was building the VM I kept the default network configuration which is NAT. I have moved away from using Bridged Adapter. A bridged adapter on the face of it is very convenient - it automatically gets an IP address via DHCP from my ISP provided router at home, in the 192.168.0.0 range. However this falls foul at client sites with security policies prohibiting unknown MAC Addresses, and Internet cafes that don't use the same IP range - it simply won't work. &lt;/p&gt;

&lt;p&gt;The solution is to use NAT and use the port forwarding facility. Navigate to &lt;em&gt;Settings -&gt; Network -&gt; Advanced -&gt; Port Forwarding&lt;/em&gt; and add values for ssh as per the third screenshot above.  &lt;/p&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;I can now ssh into the ddev VM. 
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;$ &lt;span style="color: #c20cb9; font-weight: bold;"&gt;ssh&lt;/span&gt; &lt;span style="color: #660033;"&gt;-p&lt;/span&gt; &lt;span style="color: #000000;"&gt;2222&lt;/span&gt; nigel&lt;span style="color: #000000; font-weight: bold;"&gt;@&lt;/span&gt;127.0.0.1
The authenticity of host &lt;span style="color: #ff0000;"&gt;'[127.0.0.1]:2222 ([127.0.0.1]:2222)'&lt;/span&gt; can&lt;span style="color: #ff0000;"&gt;'t be established.
ECDSA key fingerprint is SHA256:VRNxWpagSl2DGz7dmgRjBqdDdadXITdPPkItrMR9k38.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;127.0.0.1&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;:&lt;span style="color: #000000;"&gt;2222&lt;/span&gt;&lt;span style="color: #ff0000;"&gt;' (ECDSA) to the list of known hosts.
nigel@127.0.0.1'&lt;/span&gt;s password: 
Welcome to Ubuntu 16.04.3 LTS &lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;GNU&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;Linux 4.4.0-&lt;span style="color: #000000;"&gt;87&lt;/span&gt;-generic x86_64&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;
 
 &lt;span style="color: #000000; font-weight: bold;"&gt;*&lt;/span&gt; Documentation:  https:&lt;span style="color: #000000; font-weight: bold;"&gt;//&lt;/span&gt;help.ubuntu.com
 &lt;span style="color: #000000; font-weight: bold;"&gt;*&lt;/span&gt; Management:     https:&lt;span style="color: #000000; font-weight: bold;"&gt;//&lt;/span&gt;landscape.canonical.com
 &lt;span style="color: #000000; font-weight: bold;"&gt;*&lt;/span&gt; Support:        https:&lt;span style="color: #000000; font-weight: bold;"&gt;//&lt;/span&gt;ubuntu.com&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;advantage
 
&lt;span style="color: #000000;"&gt;137&lt;/span&gt; packages can be updated.
&lt;span style="color: #000000;"&gt;69&lt;/span&gt; updates are security updates.
 
 
Last login: Mon Mar  &lt;span style="color: #000000;"&gt;5&lt;/span&gt; &lt;span style="color: #000000;"&gt;21&lt;/span&gt;:&lt;span style="color: #000000;"&gt;50&lt;/span&gt;:&lt;span style="color: #000000;"&gt;35&lt;/span&gt; &lt;span style="color: #000000;"&gt;2018&lt;/span&gt;
To run a &lt;span style="color: #7a0874; font-weight: bold;"&gt;command&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;as&lt;/span&gt; administrator &lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;user &lt;span style="color: #ff0000;"&gt;"root"&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;, use &lt;span style="color: #ff0000;"&gt;"sudo &lt;command&gt;"&lt;/span&gt;.
See &lt;span style="color: #ff0000;"&gt;"man sudo_root"&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;for&lt;/span&gt; details.&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Install Docker&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;Don't be tempted to install the Docker version that is bundled in the Ubuntu default repos. Follow the instructions on the Docker site for installing the CE version of Docker from their private repo. &lt;br /&gt;&lt;br /&gt;
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #666666;"&gt;nigel@ddev:~$ &lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;sudo&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;apt-get update&lt;/span&gt;
&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;sudo&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt; password &lt;span style="color: #000000; font-weight: bold;"&gt;for&lt;/span&gt; nigel: 
Hit:&lt;span style="color: #000000;"&gt;1&lt;/span&gt; http:&lt;span style="color: #000000; font-weight: bold;"&gt;//&lt;/span&gt;security.ubuntu.com&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;ubuntu xenial-security InRelease
Hit:&lt;span style="color: #000000;"&gt;2&lt;/span&gt; http:&lt;span style="color: #000000; font-weight: bold;"&gt;//&lt;/span&gt;gb.archive.ubuntu.com&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;ubuntu xenial InRelease
Hit:&lt;span style="color: #000000;"&gt;3&lt;/span&gt; http:&lt;span style="color: #000000; font-weight: bold;"&gt;//&lt;/span&gt;gb.archive.ubuntu.com&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;ubuntu xenial-updates InRelease
Hit:&lt;span style="color: #000000;"&gt;4&lt;/span&gt; http:&lt;span style="color: #000000; font-weight: bold;"&gt;//&lt;/span&gt;gb.archive.ubuntu.com&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;ubuntu xenial-backports InRelease
Reading package lists... Done &lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
Install packages to allow apt to use a repository over HTTPS
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #666666;"&gt;nigel@ddev:~$ &lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;sudo&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;apt-get install&lt;/span&gt; \
&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;     apt-transport-https \
&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;     ca-certificates \
&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;     curl \
&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;     software-properties-common
Reading package lists... Done
Building dependency &lt;span style="color: #c20cb9; font-weight: bold;"&gt;tree&lt;/span&gt;       
Reading state information... Done
apt-transport-https is already the newest version &lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;1.2.25&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;.
ca-certificates is already the newest version &lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;&lt;span style="color: #000000;"&gt;20170717&lt;/span&gt;~16.04.1&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;.
curl is already the newest version &lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;7.47.0-1ubuntu2.6&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;.
software-properties-common is already the newest version &lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;0.96.20.7&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;.
&lt;span style="color: #000000;"&gt;0&lt;/span&gt; to upgrade, &lt;span style="color: #000000;"&gt;0&lt;/span&gt; to newly &lt;span style="color: #c20cb9; font-weight: bold;"&gt;install&lt;/span&gt;, &lt;span style="color: #000000;"&gt;0&lt;/span&gt; to remove and &lt;span style="color: #000000;"&gt;2&lt;/span&gt; not to upgrade.&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
That's good. Nothing to do there. Now let's add Docker’s official GPG key:
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #666666;"&gt;nigel@ddev:~$ &lt;/span&gt;curl &lt;span style="color: #660033;"&gt;-fsSL&lt;/span&gt; https:&lt;span style="color: #000000; font-weight: bold;"&gt;//&lt;/span&gt;download.docker.com&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;linux&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;ubuntu&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;gpg &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;sudo&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;apt-key add&lt;/span&gt; -
OK&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
Now I need to verify that we have the key with the fingerprint 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88, by searching for the last 8 characters of the fingerprint.
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #666666;"&gt;nigel@ddev:~$ &lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;sudo&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;apt-key&lt;/span&gt; fingerprint 0EBFCD88
pub   4096R&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;0EBFCD88 &lt;span style="color: #000000;"&gt;2017&lt;/span&gt;-02-&lt;span style="color: #000000;"&gt;22&lt;/span&gt;
      Key fingerprint = 9DC8 &lt;span style="color: #000000;"&gt;5822&lt;/span&gt; 9FC7 DD38 854A  E2D8 8D81 803C 0EBF CD88
uid                  Docker Release &lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;CE deb&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;&lt;&lt;/span&gt;docker&lt;span style="color: #000000; font-weight: bold;"&gt;@&lt;/span&gt;docker.com&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;
sub   4096R&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;F273FCD8 &lt;span style="color: #000000;"&gt;2017&lt;/span&gt;-02-&lt;span style="color: #000000;"&gt;22&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
All good. Next the following command to set up the stable repository.
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #666666;"&gt;nigel@ddev:~$ &lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;sudo&lt;/span&gt; add-apt-repository \
&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;    &lt;span style="color: #ff0000;"&gt;"deb [arch=amd64] https://download.docker.com/linux/ubuntu &lt;span style="color: #000099; font-weight: bold;"&gt;\
&lt;/span&gt;&gt;    &lt;span style="color: #007800;"&gt;$(lsb_release -cs)&lt;/span&gt; &lt;span style="color: #000099; font-weight: bold;"&gt;\
&lt;/span&gt;&gt;    stable"&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
Update apt again
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #666666;"&gt;nigel@ddev:~$ &lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;sudo&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;apt-get update&lt;/span&gt;
Hit:&lt;span style="color: #000000;"&gt;1&lt;/span&gt; http:&lt;span style="color: #000000; font-weight: bold;"&gt;//&lt;/span&gt;security.ubuntu.com&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;ubuntu xenial-security InRelease
Hit:&lt;span style="color: #000000;"&gt;2&lt;/span&gt; http:&lt;span style="color: #000000; font-weight: bold;"&gt;//&lt;/span&gt;gb.archive.ubuntu.com&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;ubuntu xenial InRelease
Hit:&lt;span style="color: #000000;"&gt;3&lt;/span&gt; http:&lt;span style="color: #000000; font-weight: bold;"&gt;//&lt;/span&gt;gb.archive.ubuntu.com&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;ubuntu xenial-updates InRelease
Hit:&lt;span style="color: #000000;"&gt;4&lt;/span&gt; http:&lt;span style="color: #000000; font-weight: bold;"&gt;//&lt;/span&gt;gb.archive.ubuntu.com&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;ubuntu xenial-backports InRelease
Get:&lt;span style="color: #000000;"&gt;5&lt;/span&gt; https:&lt;span style="color: #000000; font-weight: bold;"&gt;//&lt;/span&gt;download.docker.com&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;linux&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;ubuntu xenial InRelease &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #000000;"&gt;65.8&lt;/span&gt; kB&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;
Get:&lt;span style="color: #000000;"&gt;6&lt;/span&gt; https:&lt;span style="color: #000000; font-weight: bold;"&gt;//&lt;/span&gt;download.docker.com&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;linux&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;ubuntu xenial&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;stable amd64 Packages &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #000000;"&gt;3&lt;/span&gt;,&lt;span style="color: #000000;"&gt;329&lt;/span&gt; B&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;
Fetched &lt;span style="color: #000000;"&gt;69.1&lt;/span&gt; kB &lt;span style="color: #000000; font-weight: bold;"&gt;in&lt;/span&gt; 0s &lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;&lt;span style="color: #000000;"&gt;140&lt;/span&gt; kB&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;s&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;
Reading package lists... Done&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
Again we are looking good - we can see it's picked up the Docker repo ok. Let's install the latest version of Docker. 
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #666666;"&gt;nigel@ddev:~$ &lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;sudo&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;apt-get update&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
Let's check it's working..
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #666666;"&gt;nigel@ddev:~$ &lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;sudo&lt;/span&gt; docker run hello-world
&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;sudo&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt; password &lt;span style="color: #000000; font-weight: bold;"&gt;for&lt;/span&gt; nigel: 
Unable to &lt;span style="color: #c20cb9; font-weight: bold;"&gt;find&lt;/span&gt; image &lt;span style="color: #ff0000;"&gt;'hello-world:latest'&lt;/span&gt; locally
latest: Pulling from library&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;hello-world
ca4f61b1923c: Pull &lt;span style="color: #7a0874; font-weight: bold;"&gt;complete&lt;/span&gt; 
Digest: sha256:083de497cff944f969d8499ab94f07134c50bcf5e6b9559b27182d3fa80ce3f7
Status: Downloaded newer image &lt;span style="color: #000000; font-weight: bold;"&gt;for&lt;/span&gt; hello-world:latest
 
Hello from Docker&lt;span style="color: #000000; font-weight: bold;"&gt;!&lt;/span&gt;
This message shows that your installation appears to be working correctly.&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
Success! Now we need docker-compose installing. Again, don't be tempted to install from the standard Ubuntu repos, because if you do with Ubuntu 16.04LTS you'll end up with docker-compose version 1.8.0 which does not meet the ddev requirements. So do it the proper way!
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #666666;"&gt;nigel@ddev:~$ &lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;sudo&lt;/span&gt; curl &lt;span style="color: #660033;"&gt;-L&lt;/span&gt; https:&lt;span style="color: #000000; font-weight: bold;"&gt;//&lt;/span&gt;github.com&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;docker&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;compose&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;releases&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;download&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;1.19.0&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;docker-compose-&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;uname&lt;/span&gt; -s&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;-&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;uname&lt;/span&gt; -m&lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt; &lt;span style="color: #660033;"&gt;-o&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;usr&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;local&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;bin&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;docker-compose
  &lt;span style="color: #000000; font-weight: bold;"&gt;%&lt;/span&gt; Total    &lt;span style="color: #000000; font-weight: bold;"&gt;%&lt;/span&gt; Received &lt;span style="color: #000000; font-weight: bold;"&gt;%&lt;/span&gt; Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
&lt;span style="color: #000000;"&gt;100&lt;/span&gt;   &lt;span style="color: #000000;"&gt;617&lt;/span&gt;    &lt;span style="color: #000000;"&gt;0&lt;/span&gt;   &lt;span style="color: #000000;"&gt;617&lt;/span&gt;    &lt;span style="color: #000000;"&gt;0&lt;/span&gt;     &lt;span style="color: #000000;"&gt;0&lt;/span&gt;    &lt;span style="color: #000000;"&gt;795&lt;/span&gt;      &lt;span style="color: #000000;"&gt;0&lt;/span&gt; --:--:-- --:--:-- --:--:--   &lt;span style="color: #000000;"&gt;795&lt;/span&gt;
&lt;span style="color: #000000;"&gt;100&lt;/span&gt; 8288k  &lt;span style="color: #000000;"&gt;100&lt;/span&gt; 8288k    &lt;span style="color: #000000;"&gt;0&lt;/span&gt;     &lt;span style="color: #000000;"&gt;0&lt;/span&gt;   355k      &lt;span style="color: #000000;"&gt;0&lt;/span&gt;  &lt;span style="color: #000000;"&gt;0&lt;/span&gt;:00:&lt;span style="color: #000000;"&gt;23&lt;/span&gt;  &lt;span style="color: #000000;"&gt;0&lt;/span&gt;:00:&lt;span style="color: #000000;"&gt;23&lt;/span&gt; --:--:--  196k&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
Now make it executable
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #666666;"&gt;nigel@ddev:~$ &lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;sudo&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;chmod&lt;/span&gt; +x &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;usr&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;local&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;bin&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;docker-compose&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
Let's see the version
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #666666;"&gt;nigel@ddev:~$ &lt;/span&gt;docker-compose &lt;span style="color: #660033;"&gt;--version&lt;/span&gt;
docker-compose version 1.19.0, build 9e633ef&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
Neat! We are almost there. Now we need to make sure Docker starts every time we boot the machine.
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;nigel&lt;span style="color: #000000; font-weight: bold;"&gt;@&lt;/span&gt;ddev:~&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;projects&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;meedjum$ &lt;span style="color: #c20cb9; font-weight: bold;"&gt;sudo&lt;/span&gt; systemctl &lt;span style="color: #7a0874; font-weight: bold;"&gt;enable&lt;/span&gt; docker
Synchronizing state of docker.service with SysV init with &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;lib&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;systemd&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;systemd-sysv-install...
Executing &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;lib&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;systemd&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;systemd-sysv-install &lt;span style="color: #7a0874; font-weight: bold;"&gt;enable&lt;/span&gt; docker&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
Before I am done here, I need to add myself to the Docker group so I can execute Docker commands (or rather ddev can on my behalf)
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #666666;"&gt;nigel@ddev:~/projects/meedjum$ &lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;sudo&lt;/span&gt; usermod &lt;span style="color: #660033;"&gt;-aG&lt;/span&gt; docker $&lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;whoami&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
Rebooting will now serve two purposes - check that the above command works which will start Docker, and make sure my new group status has been picked up. 
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;nigel&lt;span style="color: #000000; font-weight: bold;"&gt;@&lt;/span&gt;ddev:~&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;projects&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;meedjum$ &lt;span style="color: #c20cb9; font-weight: bold;"&gt;sudo&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;su&lt;/span&gt;
root&lt;span style="color: #000000; font-weight: bold;"&gt;@&lt;/span&gt;ddev:&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;home&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;nigel&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;projects&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;meedjum&lt;span style="color: #666666; font-style: italic;"&gt;# init 6&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Installing ddev&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;&lt;p&gt;There are two ways of installing ddev - by downloading from the repository's &lt;a href="https://github.com/drud/ddev/releases"&gt;releases&lt;/a&gt; - or use the install script in the &lt;a href="https://ddev.readthedocs.io/en/latest/"&gt;ddev&lt;/a&gt; documentation. I opted for the latter. &lt;/p&gt;
&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #666666;"&gt;nigel@ddev:~$ &lt;/span&gt;curl https:&lt;span style="color: #000000; font-weight: bold;"&gt;//&lt;/span&gt;raw.githubusercontent.com&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;drud&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;ddev&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;master&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;install_ddev.sh &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;bash&lt;/span&gt;
  &lt;span style="color: #000000; font-weight: bold;"&gt;%&lt;/span&gt; Total    &lt;span style="color: #000000; font-weight: bold;"&gt;%&lt;/span&gt; Received &lt;span style="color: #000000; font-weight: bold;"&gt;%&lt;/span&gt; Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
&lt;span style="color: #000000;"&gt;100&lt;/span&gt;  &lt;span style="color: #000000;"&gt;2545&lt;/span&gt;  &lt;span style="color: #000000;"&gt;100&lt;/span&gt;  &lt;span style="color: #000000;"&gt;2545&lt;/span&gt;    &lt;span style="color: #000000;"&gt;0&lt;/span&gt;     &lt;span style="color: #000000;"&gt;0&lt;/span&gt;   &lt;span style="color: #000000;"&gt;5821&lt;/span&gt;      &lt;span style="color: #000000;"&gt;0&lt;/span&gt; --:--:-- --:--:-- --:--:--  &lt;span style="color: #000000;"&gt;5823&lt;/span&gt;
ddev_linux.v0.15.0.tar.gz: OK
Download verified. Ready to place ddev &lt;span style="color: #000000; font-weight: bold;"&gt;in&lt;/span&gt; your &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;usr&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;local&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;bin.
Running &lt;span style="color: #ff0000;"&gt;"sudo mv /tmp/ddev /usr/local/bin/"&lt;/span&gt; Please enter your password &lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; prompted.
&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;sudo&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt; password &lt;span style="color: #000000; font-weight: bold;"&gt;for&lt;/span&gt; nigel: 
Bash completion &lt;span style="color: #000000; font-weight: bold;"&gt;for&lt;/span&gt; ddev was not installed. You may manually &lt;span style="color: #c20cb9; font-weight: bold;"&gt;install&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;tmp&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;ddev_bash_completion.sh &lt;span style="color: #000000; font-weight: bold;"&gt;in&lt;/span&gt; your bash_completions.d directory.
ddev is now installed. Run &lt;span style="color: #ff0000;"&gt;"ddev"&lt;/span&gt; to verify your installation and see usage.&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
Installed - now check our installation
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #666666;"&gt;nigel@ddev:~$ &lt;/span&gt;ddev
This Command Line Interface &lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;CLI&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt; gives you the ability to interact with the ddev to create a development environment.
 
Usage:
  ddev &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;command&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt;
 
Available Commands:
  auth-pantheon Provide a machine token &lt;span style="color: #000000; font-weight: bold;"&gt;for&lt;/span&gt; the global pantheon auth.
  config        Create or modify a ddev project configuration &lt;span style="color: #000000; font-weight: bold;"&gt;in&lt;/span&gt; the current directory
  describe      Get a detailed description of a running ddev project.
  &lt;span style="color: #7a0874; font-weight: bold;"&gt;exec&lt;/span&gt;          Execute a shell &lt;span style="color: #7a0874; font-weight: bold;"&gt;command&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;in&lt;/span&gt; the container &lt;span style="color: #000000; font-weight: bold;"&gt;for&lt;/span&gt; a service. Uses the web service by default.
  &lt;span style="color: #7a0874; font-weight: bold;"&gt;help&lt;/span&gt;          Help about any &lt;span style="color: #7a0874; font-weight: bold;"&gt;command&lt;/span&gt;
  &lt;span style="color: #c20cb9; font-weight: bold;"&gt;hostname&lt;/span&gt;      Manage your hostfile entries.
  import-db     Import the database of an existing project to the dev environment.
  import-files  Import the uploaded files directory of an existing project to the default public upload directory of your project.
  list          List projects
  logs          Get the logs from your running services.
  pull          Import files and database using a configured provider plugin.
  remove        Remove the development environment &lt;span style="color: #000000; font-weight: bold;"&gt;for&lt;/span&gt; a project.
  restart       Restart the development environment &lt;span style="color: #000000; font-weight: bold;"&gt;for&lt;/span&gt; a project.
  &lt;span style="color: #c20cb9; font-weight: bold;"&gt;ssh&lt;/span&gt;           Starts a shell session &lt;span style="color: #000000; font-weight: bold;"&gt;in&lt;/span&gt; the container &lt;span style="color: #000000; font-weight: bold;"&gt;for&lt;/span&gt; a service. Uses web service by default.
  start         Start a ddev project.
  stop          Stop the development environment &lt;span style="color: #000000; font-weight: bold;"&gt;for&lt;/span&gt; a project.
  version       print ddev version and component versions
 
Flags:
  -h, &lt;span style="color: #660033;"&gt;--help&lt;/span&gt;          &lt;span style="color: #7a0874; font-weight: bold;"&gt;help&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;for&lt;/span&gt; ddev
  -j, &lt;span style="color: #660033;"&gt;--json-output&lt;/span&gt;   If &lt;span style="color: #c20cb9; font-weight: bold;"&gt;true&lt;/span&gt;, user-oriented output will be &lt;span style="color: #000000; font-weight: bold;"&gt;in&lt;/span&gt; JSON format.
 
Use &lt;span style="color: #ff0000;"&gt;"ddev [command] --help"&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;for&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;more&lt;/span&gt; information about a command.&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
We have it!&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Getting Started with an Existing Drupal 8 Project&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;This blog has been built using Drupal 8 - so it made sense to use this for my first project. Let's create a directory for my projects and git clone. At this point I had already created a new .ssh key for my ddev VM and added it to my GitHub profile.
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #666666;"&gt;nigel@ddev:~$ &lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;mkdir&lt;/span&gt; projects
&lt;span style="color: #666666;"&gt;nigel@ddev:~$ &lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;cd&lt;/span&gt; projects&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;
nigel&lt;span style="color: #000000; font-weight: bold;"&gt;@&lt;/span&gt;ddev:~&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;projects$ &lt;span style="color: #c20cb9; font-weight: bold;"&gt;git clone&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;git&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;@&lt;/span&gt;github.com:sanddevil&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;meedjum.git
Cloning into &lt;span style="color: #ff0000;"&gt;'meedjum'&lt;/span&gt;...&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
Now let's cd into the project and config ddev for our Drupal 8 through its interactive shell. 
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;nigel&lt;span style="color: #000000; font-weight: bold;"&gt;@&lt;/span&gt;ddev:~&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;projects&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;meedjum$ ddev config
Creating a new ddev project config &lt;span style="color: #000000; font-weight: bold;"&gt;in&lt;/span&gt; the current directory &lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;home&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;nigel&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;projects&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;meedjum&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt; 
Once completed, your configuration will be written to &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;home&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;nigel&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;projects&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;meedjum&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;.ddev&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;config.yaml
 
Project name &lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;meedjum&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;: 
 
The docroot is the directory from &lt;span style="color: #c20cb9; font-weight: bold;"&gt;which&lt;/span&gt; your site is served. This is a relative path from your project root &lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;home&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;nigel&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;projects&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;meedjum&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt; 
You may leave this value blank &lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; your site files are &lt;span style="color: #000000; font-weight: bold;"&gt;in&lt;/span&gt; the project root 
Docroot Location &lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;docroot&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;: 
Found a php codebase at &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;home&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;nigel&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;projects&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;meedjum&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;docroot. 
Project Type &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;php, drupal6, drupal7, drupal8, wordpress, typo3, backdrop&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;php&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;: drupal8
Configuration complete. You may now run &lt;span style="color: #ff0000;"&gt;'ddev start'&lt;/span&gt;. &lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
ddev is suggesting I should run start, so why not?
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;nigel&lt;span style="color: #000000; font-weight: bold;"&gt;@&lt;/span&gt;ddev:~&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;projects&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;meedjum$ ddev start
Network ddev_default created 
Starting environment &lt;span style="color: #000000; font-weight: bold;"&gt;for&lt;/span&gt; meedjum... 
ddev needs to add an entry to your hostfile.
It will require root privileges via the &lt;span style="color: #c20cb9; font-weight: bold;"&gt;sudo&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;command&lt;/span&gt;, so you may be required
to enter your password &lt;span style="color: #000000; font-weight: bold;"&gt;for&lt;/span&gt; sudo. ddev is about to issue the command: 
    &lt;span style="color: #c20cb9; font-weight: bold;"&gt;sudo&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;usr&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;local&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;bin&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;ddev &lt;span style="color: #c20cb9; font-weight: bold;"&gt;hostname&lt;/span&gt; meedjum.ddev.local 127.0.0.1 
Please enter your password &lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; prompted. 
Running Command  &lt;span style="color: #007800;"&gt;Command&lt;/span&gt;=&lt;span style="color: #c20cb9; font-weight: bold;"&gt;sudo&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;usr&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;local&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;bin&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;ddev &lt;span style="color: #c20cb9; font-weight: bold;"&gt;hostname&lt;/span&gt; meedjum.ddev.local 127.0.0.1
&lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;sudo&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt; password &lt;span style="color: #000000; font-weight: bold;"&gt;for&lt;/span&gt; nigel: 
Pulling db &lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;drud&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;mariadb-local:v0.8.0&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;... 
Creating ddev-meedjum-db ... &lt;span style="color: #000000; font-weight: bold;"&gt;done&lt;/span&gt;
Pulling dba &lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;drud&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;phpmyadmin:v0.2.0&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;... 
Creating ddev-meedjum-web ... &lt;span style="color: #000000; font-weight: bold;"&gt;done&lt;/span&gt;
Creating ddev-meedjum-dba ...  
Creating ddev-meedjum-web ...  
 
Network ddev_default is external, skipping 
Pulling ddev-router &lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;drud&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;ddev-router:v0.5.0&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;... 
Creating ddev-router ... &lt;span style="color: #000000; font-weight: bold;"&gt;done&lt;/span&gt;
 
Successfully started meedjum 
Your project can be reached at http:&lt;span style="color: #000000; font-weight: bold;"&gt;//&lt;/span&gt;meedjum.ddev.local and https:&lt;span style="color: #000000; font-weight: bold;"&gt;//&lt;/span&gt;meedjum.ddev.local &lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Installing Composer&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;Drupal 8 requires composer and that needs installing on our clean system. There are plenty of tutorials online on how to achieve this, so I'll whizz through this quickly. 
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #666666;"&gt;nigel@ddev:~$ &lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;sudo&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;apt-get update&lt;/span&gt;
Hit:&lt;span style="color: #000000;"&gt;1&lt;/span&gt; http:&lt;span style="color: #000000; font-weight: bold;"&gt;//&lt;/span&gt;security.ubuntu.com&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;ubuntu xenial-security InRelease
Hit:&lt;span style="color: #000000;"&gt;2&lt;/span&gt; http:&lt;span style="color: #000000; font-weight: bold;"&gt;//&lt;/span&gt;gb.archive.ubuntu.com&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;ubuntu xenial InRelease
Hit:&lt;span style="color: #000000;"&gt;3&lt;/span&gt; http:&lt;span style="color: #000000; font-weight: bold;"&gt;//&lt;/span&gt;gb.archive.ubuntu.com&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;ubuntu xenial-updates InRelease
Hit:&lt;span style="color: #000000;"&gt;4&lt;/span&gt; http:&lt;span style="color: #000000; font-weight: bold;"&gt;//&lt;/span&gt;gb.archive.ubuntu.com&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;ubuntu xenial-backports InRelease
Hit:&lt;span style="color: #000000;"&gt;5&lt;/span&gt; https:&lt;span style="color: #000000; font-weight: bold;"&gt;//&lt;/span&gt;download.docker.com&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;linux&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;ubuntu xenial InRelease
Reading package lists... Done&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
Install the dependencies
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #666666;"&gt;nigel@ddev:~$ &lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;sudo&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;apt-get install&lt;/span&gt; curl php-cli php-mbstring &lt;span style="color: #c20cb9; font-weight: bold;"&gt;git&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;unzip&lt;/span&gt;
Reading package lists... Done&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
Download composer
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #666666;"&gt;nigel@ddev:~$ &lt;/span&gt;curl &lt;span style="color: #660033;"&gt;-sS&lt;/span&gt; https:&lt;span style="color: #000000; font-weight: bold;"&gt;//&lt;/span&gt;getcomposer.org&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;installer &lt;span style="color: #660033;"&gt;-o&lt;/span&gt; composer-setup.php&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
Install it globally
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #666666;"&gt;nigel@ddev:~$ &lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;sudo&lt;/span&gt; php composer-setup.php &lt;span style="color: #660033;"&gt;--install-dir&lt;/span&gt;=&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;usr&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;local&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;bin &lt;span style="color: #660033;"&gt;--filename&lt;/span&gt;=composer
All settings correct &lt;span style="color: #000000; font-weight: bold;"&gt;for&lt;/span&gt; using Composer
Downloading...
 
Composer &lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;version 1.6.3&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt; successfully installed to: &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;usr&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;local&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;bin&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;composer
Use it: php &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;usr&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;local&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;bin&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;composer&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
Now check it's been installed correctly
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #666666;"&gt;nigel@ddev:~$ &lt;/span&gt;composer
   ______
  &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt; ____&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;___  ____ ___  ____  ____  ________  _____
 &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;   &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt; __ \&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt; __ &lt;span style="color: #000000; font-weight: bold;"&gt;`&lt;/span&gt;__ \&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt; __ \&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt; __ \&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt; ___&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt; _ \&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt; ___&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;___&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;_&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;_&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;_&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;__  &lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;  __&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;
\____&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;\____&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;_&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;_&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;_&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt; .___&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;\____&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;____&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;\___&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;_&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;
                    &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;_&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;
Composer version 1.6.3 &lt;span style="color: #000000;"&gt;2018&lt;/span&gt;-01-&lt;span style="color: #000000;"&gt;31&lt;/span&gt; &lt;span style="color: #000000;"&gt;16&lt;/span&gt;:&lt;span style="color: #000000;"&gt;28&lt;/span&gt;:&lt;span style="color: #000000;"&gt;17&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Building Out the Drupal 8 Project&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;&lt;p&gt;The &lt;i&gt;ddev start&lt;/i&gt; command creates a new subdirectory called &lt;strong&gt;.ddev&lt;/strong&gt; in the project's root directory. Within the directory we have &lt;strong&gt;config.yaml&lt;/strong&gt; and  &lt;strong&gt;docker-compose.yaml&lt;/strong&gt;. The config file contains the configuration of our ddev project such as the version of PHP, webpage url, type of project (drupal8) amongst other items. The docker yaml file contains the container configuration. &lt;/p&gt;
&lt;p&gt;Interaction with the ddev project can be accomplished in two ways, either with &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ddev exec &lt;em&gt;command&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;or by spawning a shell with&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ddev ssh&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;and using &lt;strong&gt;exit&lt;/strong&gt; to terminate the interactive session. &lt;/p&gt;
&lt;p&gt;Our first requirement is to get dependencies into our D8 project since it is vendor-ised and uses &lt;strong&gt;composer&lt;/strong&gt; as its dependency management.&lt;/p&gt;
&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;Ok my Drupal core was on 8.4.4 and 8.4.5 and then 8.5 had been released so it needed updating, and in my case would update to 8.4.5 initially 
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;nigel&lt;span style="color: #000000; font-weight: bold;"&gt;@&lt;/span&gt;ddev:~&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;projects&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;meedjum&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;docroot$ composer update &lt;span style="color: #660033;"&gt;--with-dependencies&lt;/span&gt;
Gathering patches &lt;span style="color: #000000; font-weight: bold;"&gt;for&lt;/span&gt; root package.
Loading composer repositories with package information
Updating dependencies &lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;including require-dev&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;
Package operations: &lt;span style="color: #000000;"&gt;51&lt;/span&gt; installs, &lt;span style="color: #000000;"&gt;0&lt;/span&gt; updates, &lt;span style="color: #000000;"&gt;0&lt;/span&gt; removals
Gathering patches &lt;span style="color: #000000; font-weight: bold;"&gt;for&lt;/span&gt; root package.
Gathering patches &lt;span style="color: #000000; font-weight: bold;"&gt;for&lt;/span&gt; dependencies. This might take a minute.&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
Now since there were schema changes, those need to be applied. 
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;nigel&lt;span style="color: #000000; font-weight: bold;"&gt;@&lt;/span&gt;ddev:~&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;projects&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;meedjum&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;docroot$ ddev &lt;span style="color: #7a0874; font-weight: bold;"&gt;exec&lt;/span&gt; drush &lt;span style="color: #c20cb9; font-weight: bold;"&gt;updatedb&lt;/span&gt;
Performing node_update_8401                                          &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;ok&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt; 
Cache rebuild complete.                                              &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;ok&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt; 
Finished performing updates.                                         &lt;span style="color: #7a0874; font-weight: bold;"&gt;[&lt;/span&gt;ok&lt;span style="color: #7a0874; font-weight: bold;"&gt;]&lt;/span&gt; 
The following updates are pending:
 
node module : 
  &lt;span style="color: #000000;"&gt;8401&lt;/span&gt; -   Run a node access rebuild, &lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; required. 
 
Do you wish to run all pending updates? &lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;y&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;n&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;: y&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Settings.php&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;&lt;p&gt;This is where things started to go awry. I already have a fully constructed &lt;strong&gt;settings.php&lt;/strong&gt; and &lt;strong&gt;settings.local.php&lt;/strong&gt;. The settings.php file contains my Memcached settings. However the memcache(d) PHP libraries aren't shipped in the ddev product. Obviously by that fact ddev doesn't support Memcached. &lt;/p&gt;
&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;When I attempted a drush status command I was inundated with errors. 
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;nigel&lt;span style="color: #000000; font-weight: bold;"&gt;@&lt;/span&gt;ddev:~&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;projects&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;meedjum&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;docroot&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;sites&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;default$ &lt;span style="color: #c20cb9; font-weight: bold;"&gt;vi&lt;/span&gt; settings.local.php
nigel&lt;span style="color: #000000; font-weight: bold;"&gt;@&lt;/span&gt;ddev:~&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;projects&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;meedjum&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;docroot&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;sites&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;default$ ddev &lt;span style="color: #7a0874; font-weight: bold;"&gt;exec&lt;/span&gt; drush status
Drupal\memcache\MemcacheException: No Memcache extension found &lt;span style="color: #000000; font-weight: bold;"&gt;in&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;var&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;www&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;html&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;docroot&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;modules&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;contrib&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;memcache&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;src&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;DrupalMemcacheFactory.php on line &lt;span style="color: #000000;"&gt;162&lt;/span&gt; &lt;span style="color: #666666; font-style: italic;"&gt;#0 /var/www/html/docroot/modules/contrib/memcache/src/DrupalMemcacheFactory.php(62): Drupal\memcache\DrupalMemcacheFactory-&gt;initialize() &lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
As a consequence I commented out the Memcache settings
&lt;div class="codeblock geshifilter"&gt;&lt;code&gt;&lt;span style="color: #000000"&gt;&lt;span style="color: #0000BB"&gt;&lt;?php&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #FF8000"&gt;// Memcache&lt;br /&gt;//Memcache configuration&lt;br /&gt;//$settings['memcache']['servers'] = ['127.0.0.1:11211' =&gt; 'default'];&lt;br /&gt;//$settings['memcache']['bins'] = ['default' =&gt; 'default'];&lt;br /&gt;//$settings['memcache']['key_prefix'] = 'badzillad8';&lt;br /&gt;//$settings['cache']['default'] = 'cache.backend.memcache';&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000BB"&gt;?&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Importing the Database&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;The next problem is ddev looks for the db credentials in settings.php whereas I have my credentials in my settings.local.php file. I changed the credentials in the settings.local.php file and I copied my database file to the /tmp directory. 
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;nigel&lt;span style="color: #000000; font-weight: bold;"&gt;@&lt;/span&gt;ddev:~&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;projects&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;meedjum&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;docroot&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;sites&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;default$ ddev import-db  &lt;span style="color: #660033;"&gt;--extract-path&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;tmp
Provide the path to the database you wish to import. 
Import path: &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;tmp&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;db-&lt;span style="color: #000000;"&gt;2018&lt;/span&gt;-03-&lt;span style="color: #000000;"&gt;10&lt;/span&gt;.sql.gz
Failed to import database &lt;span style="color: #000000; font-weight: bold;"&gt;for&lt;/span&gt; meedjum: failed to &lt;span style="color: #c20cb9; font-weight: bold;"&gt;write&lt;/span&gt; settings &lt;span style="color: #c20cb9; font-weight: bold;"&gt;file&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;for&lt;/span&gt; meedjum: Failed to get Drupal settings &lt;span style="color: #c20cb9; font-weight: bold;"&gt;file&lt;/span&gt; path: settings files already exist and are being managed by the user &lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
More errors! The import failed. I thought it could be because it required the credentials in settings.php but that didn't work either. So I decided to use Drush instead:
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #666666;"&gt;nigel@ddev:~/projects/meedjum/docroot/sites/default$ &lt;/span&gt;ddev &lt;span style="color: #7a0874; font-weight: bold;"&gt;exec&lt;/span&gt; drush sql-cli &lt;span style="color: #000000; font-weight: bold;"&gt;&lt;&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;tmp&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;db-&lt;span style="color: #000000;"&gt;2018&lt;/span&gt;-03-&lt;span style="color: #000000;"&gt;10&lt;/span&gt;.sql&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;HTTP Port Forwarding&lt;/div&gt;
      
      &lt;div class="field field--name-field-blog-image field--type-image field--label-hidden field--items"&gt;
              &lt;div class="field--item"&gt;    &lt;img srcset="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2018-03/Screen%20Shot%202018-03-10%20at%2015.46.21.png?itok=hMzNpeQj 325w, https://assets.badzilla.co.uk/s3fs-public/styles/max_650x650/public/2018-03/Screen%20Shot%202018-03-10%20at%2015.46.21.png?itok=19ElDITG 650w, https://assets.badzilla.co.uk/s3fs-public/styles/max_1300x1300/public/2018-03/Screen%20Shot%202018-03-10%20at%2015.46.21.png?itok=stTO3iQK 1300w, https://assets.badzilla.co.uk/s3fs-public/styles/max_2600x2600/public/2018-03/Screen%20Shot%202018-03-10%20at%2015.46.21.png?itok=Kmlp-Ivk 1526w" sizes="(min-width: 1290px) 1290px, 100vw" src="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2018-03/Screen%20Shot%202018-03-10%20at%2015.46.21.png?itok=hMzNpeQj" alt="HTTP Port Forward" typeof="foaf:Image" class="img-responsive" /&gt;


&lt;/div&gt;
              &lt;div class="field--item"&gt;    &lt;img srcset="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2018-03/Screen%20Shot%202018-03-10%20at%2017.03.59.png?itok=paAus2c1 325w, https://assets.badzilla.co.uk/s3fs-public/styles/max_650x650/public/2018-03/Screen%20Shot%202018-03-10%20at%2017.03.59.png?itok=1lyjZtih 650w, https://assets.badzilla.co.uk/s3fs-public/styles/max_1300x1300/public/2018-03/Screen%20Shot%202018-03-10%20at%2017.03.59.png?itok=o7fpGydO 1300w, https://assets.badzilla.co.uk/s3fs-public/styles/max_2600x2600/public/2018-03/Screen%20Shot%202018-03-10%20at%2017.03.59.png?itok=u7dhNeop 1326w" sizes="(min-width: 1290px) 1290px, 100vw" src="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2018-03/Screen%20Shot%202018-03-10%20at%2017.03.59.png?itok=paAus2c1" alt="Localhost domain" typeof="foaf:Image" class="img-responsive" /&gt;


&lt;/div&gt;
              &lt;div class="field--item"&gt;    &lt;img srcset="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2018-03/Screen%20Shot%202018-03-10%20at%2017.16.13.png?itok=vZm4Hvoe 325w, https://assets.badzilla.co.uk/s3fs-public/styles/max_650x650/public/2018-03/Screen%20Shot%202018-03-10%20at%2017.16.13.png?itok=f3fWRXdM 650w, https://assets.badzilla.co.uk/s3fs-public/styles/max_1300x1300/public/2018-03/Screen%20Shot%202018-03-10%20at%2017.16.13.png?itok=1PaW4psd 1300w, https://assets.badzilla.co.uk/s3fs-public/styles/max_2600x2600/public/2018-03/Screen%20Shot%202018-03-10%20at%2017.16.13.png?itok=eHu0PxkP 1688w" sizes="(min-width: 1290px) 1290px, 100vw" src="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2018-03/Screen%20Shot%202018-03-10%20at%2017.16.13.png?itok=vZm4Hvoe" alt="Error 40x" typeof="foaf:Image" class="img-responsive" /&gt;


&lt;/div&gt;
          &lt;/div&gt;
  
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;Just like our earlier forwarding of the ssh port so we can log into the VM, we also have to forward http port 80 traffic. To do this, we go back to the virtual machine network configuration, and set up a redirect from port 9090 (somewhat arbitrary) on the host to port 80 on the guest. See the first screenshot. This will take us to the the default website on the VM. We need to explicitly tell a browser which site it is - to do that we add an entry on the machine where we will be using our browser - which in my case will be my MacBook.
&lt;br /&gt;&lt;br /&gt;
So I have added the entry to /etc/hosts of the working ddev domain name and the localhost IP address
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;127.0.0.1       localhost
255.255.255.255 broadcasthost
::&lt;span style="color: #000000;"&gt;1&lt;/span&gt;             localhost
 
127.0.0.1 meedjum.ddev.local&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
Now we need to reboot our VM and then login back in and issue a ddev start on our project. We can also check whether everything is good with a docker ps command. 
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;root&lt;span style="color: #000000; font-weight: bold;"&gt;@&lt;/span&gt;ddev:&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;home&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;nigel&lt;span style="color: #666666; font-style: italic;"&gt;# init 6&lt;/span&gt;
Connection to 127.0.0.1 closed by remote host.
Connection to 127.0.0.1 closed.
Nigels-MacBook-Pro:tmp nigel$ &lt;span style="color: #c20cb9; font-weight: bold;"&gt;ssh&lt;/span&gt; &lt;span style="color: #660033;"&gt;-p&lt;/span&gt; &lt;span style="color: #000000;"&gt;2222&lt;/span&gt; nigel&lt;span style="color: #000000; font-weight: bold;"&gt;@&lt;/span&gt;127.0.0.1
&lt;span style="color: #666666;"&gt;nigel@ddev:~$ &lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;cd&lt;/span&gt; projects&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;meedjum&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;
nigel&lt;span style="color: #000000; font-weight: bold;"&gt;@&lt;/span&gt;ddev:~&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;projects&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;meedjum$ ddev start
Starting environment &lt;span style="color: #000000; font-weight: bold;"&gt;for&lt;/span&gt; meedjum... 
nigel&lt;span style="color: #000000; font-weight: bold;"&gt;@&lt;/span&gt;ddev:~&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;projects&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;meedjum$ docker &lt;span style="color: #c20cb9; font-weight: bold;"&gt;ps&lt;/span&gt;
CONTAINER ID        IMAGE                             COMMAND                  CREATED             STATUS                             PORTS                                                                                      NAMES
5fd9a60cb90c        drud&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;ddev-router:v0.5.0           &lt;span style="color: #ff0000;"&gt;"/app/docker-entrypo…"&lt;/span&gt;   &lt;span style="color: #000000;"&gt;10&lt;/span&gt; seconds ago      Up &lt;span style="color: #000000;"&gt;10&lt;/span&gt; seconds &lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;healthy&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;            0.0.0.0:&lt;span style="color: #000000;"&gt;80&lt;/span&gt;-&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;80&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;tcp, 0.0.0.0:&lt;span style="color: #000000;"&gt;443&lt;/span&gt;-&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;443&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;tcp, 0.0.0.0:&lt;span style="color: #000000;"&gt;8025&lt;/span&gt;-&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;8025&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;tcp, 0.0.0.0:&lt;span style="color: #000000;"&gt;8036&lt;/span&gt;-&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;8036&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;tcp   ddev-router
cea77b7cbc6b        drud&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;nginx-php-fpm-local:v1.1.0   &lt;span style="color: #ff0000;"&gt;"/start.sh"&lt;/span&gt;              &lt;span style="color: #000000;"&gt;7&lt;/span&gt; hours ago         Up &lt;span style="color: #000000;"&gt;11&lt;/span&gt; seconds &lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;healthy&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;            &lt;span style="color: #000000;"&gt;443&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;tcp, 0.0.0.0:&lt;span style="color: #000000;"&gt;32771&lt;/span&gt;-&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;80&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;tcp, 0.0.0.0:&lt;span style="color: #000000;"&gt;32770&lt;/span&gt;-&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;8025&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;tcp                                    ddev-meedjum-web
2dc08e116820        drud&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;phpmyadmin:v0.2.0            &lt;span style="color: #ff0000;"&gt;"/run.sh phpmyadmin"&lt;/span&gt;     &lt;span style="color: #000000;"&gt;7&lt;/span&gt; hours ago         Up &lt;span style="color: #000000;"&gt;11&lt;/span&gt; seconds &lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;health: starting&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;   0.0.0.0:&lt;span style="color: #000000;"&gt;32769&lt;/span&gt;-&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;80&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;tcp                                                                      ddev-meedjum-dba
f239a52ae806        drud&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;mariadb-local:v0.8.0         &lt;span style="color: #ff0000;"&gt;"/docker-entrypoint.…"&lt;/span&gt;   &lt;span style="color: #000000;"&gt;7&lt;/span&gt; hours ago         Up &lt;span style="color: #000000;"&gt;12&lt;/span&gt; seconds &lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;healthy&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt;            0.0.0.0:&lt;span style="color: #000000;"&gt;32768&lt;/span&gt;-&lt;span style="color: #000000; font-weight: bold;"&gt;&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;3306&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;tcp                                                                    ddev-meedjum-db&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
We can now point a web browser at the url we typed into our /etc/hosts file - see third image above. Ok - so we are close but not quite there yet! Looks like this could be the old trusted host pattern issue since it doesn't know about my domain meedjum.ddev.test.&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Add ddev Domain to Trusted Hosts in Settings.php&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;...or rather in my case my settings.local.php file. I added the ddev domain name to the trusted hosts pattern array
&lt;div class="codeblock geshifilter"&gt;&lt;code&gt;&lt;span style="color: #000000"&gt;&lt;span style="color: #0000BB"&gt;&lt;?php&lt;br /&gt;$settings&lt;/span&gt;&lt;span style="color: #007700"&gt;[&lt;/span&gt;&lt;span style="color: #DD0000"&gt;'trusted_host_patterns'&lt;/span&gt;&lt;span style="color: #007700"&gt;] = [&lt;br /&gt;  &lt;/span&gt;&lt;span style="color: #DD0000"&gt;'meedjum.test'&lt;/span&gt;&lt;span style="color: #007700"&gt;,&lt;br /&gt;  &lt;/span&gt;&lt;span style="color: #DD0000"&gt;'meedjum.ddev.local'&lt;/span&gt;&lt;span style="color: #007700"&gt;,&lt;br /&gt;];&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000BB"&gt;?&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Copying the Assets&lt;/div&gt;
      
      &lt;div class="field field--name-field-blog-image field--type-image field--label-hidden field--items"&gt;
              &lt;div class="field--item"&gt;    &lt;img srcset="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2018-03/Screen%20Shot%202018-03-11%20at%2009.26.38.png?itok=pQrRE3Ve 325w, https://assets.badzilla.co.uk/s3fs-public/styles/max_650x650/public/2018-03/Screen%20Shot%202018-03-11%20at%2009.26.38.png?itok=3T_aByhp 650w, https://assets.badzilla.co.uk/s3fs-public/styles/max_1300x1300/public/2018-03/Screen%20Shot%202018-03-11%20at%2009.26.38.png?itok=bU1BJaRD 1300w, https://assets.badzilla.co.uk/s3fs-public/styles/max_2600x2600/public/2018-03/Screen%20Shot%202018-03-11%20at%2009.26.38.png?itok=mYJLCWoc 2444w" sizes="(min-width: 1290px) 1290px, 100vw" src="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2018-03/Screen%20Shot%202018-03-11%20at%2009.26.38.png?itok=pQrRE3Ve" alt="No images" typeof="foaf:Image" class="img-responsive" /&gt;


&lt;/div&gt;
          &lt;/div&gt;
  
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;Adding the trusted host entry now means the web site loads successfully but of course the assets are missing and need copying down from my prod site. ddev provides a command for this:
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;nigel&lt;span style="color: #000000; font-weight: bold;"&gt;@&lt;/span&gt;ddev:~&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;projects&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;meedjum&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;docroot$ ddev import-files &lt;span style="color: #660033;"&gt;--src&lt;/span&gt;=&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;tmp&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;files.tar.gz
Successfully imported files &lt;span style="color: #000000; font-weight: bold;"&gt;for&lt;/span&gt; meedjum &lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
100% my fault, but my file structure ended up as sites/default/files/files because I'd tarballed my prod files directory within the tarball, instead of just its contents. So I moved everything back one directory. 
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;nigel&lt;span style="color: #000000; font-weight: bold;"&gt;@&lt;/span&gt;ddev:~&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;projects&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;meedjum&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;docroot$ &lt;span style="color: #c20cb9; font-weight: bold;"&gt;mv&lt;/span&gt; sites&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;default&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;files&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;files&lt;span style="color: #000000; font-weight: bold;"&gt;/*&lt;/span&gt; sites&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;default&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;files&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;.
nigel&lt;span style="color: #000000; font-weight: bold;"&gt;@&lt;/span&gt;ddev:~&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;projects&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;meedjum&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;docroot$ &lt;span style="color: #c20cb9; font-weight: bold;"&gt;mv&lt;/span&gt; sites&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;default&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;files&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;files&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;.htaccess sites&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;default&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;files&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;.
nigel&lt;span style="color: #000000; font-weight: bold;"&gt;@&lt;/span&gt;ddev:~&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;projects&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;meedjum&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;docroot$ &lt;span style="color: #c20cb9; font-weight: bold;"&gt;rmdir&lt;/span&gt; sites&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;default&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;files&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;files&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Completed Project&lt;/div&gt;
      
      &lt;div class="field field--name-field-blog-image field--type-image field--label-hidden field--items"&gt;
              &lt;div class="field--item"&gt;    &lt;img srcset="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2018-03/Screen%20Shot%202018-03-11%20at%2010.08.06.png?itok=KRAPhIbF 325w, https://assets.badzilla.co.uk/s3fs-public/styles/max_650x650/public/2018-03/Screen%20Shot%202018-03-11%20at%2010.08.06.png?itok=7L9fTv8R 650w, https://assets.badzilla.co.uk/s3fs-public/styles/max_1300x1300/public/2018-03/Screen%20Shot%202018-03-11%20at%2010.08.06.png?itok=6iGL9DEv 1300w, https://assets.badzilla.co.uk/s3fs-public/styles/max_2600x2600/public/2018-03/Screen%20Shot%202018-03-11%20at%2010.08.06.png?itok=11PErvGZ 2482w" sizes="(min-width: 1290px) 1290px, 100vw" src="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2018-03/Screen%20Shot%202018-03-11%20at%2010.08.06.png?itok=KRAPhIbF" alt="Complete Blog" typeof="foaf:Image" class="img-responsive" /&gt;


&lt;/div&gt;
              &lt;div class="field--item"&gt;    &lt;img srcset="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2018-03/Screen%20Shot%202018-03-11%20at%2010.09.27.png?itok=3UGeLQMw 325w, https://assets.badzilla.co.uk/s3fs-public/styles/max_650x650/public/2018-03/Screen%20Shot%202018-03-11%20at%2010.09.27.png?itok=3TCbywLN 650w, https://assets.badzilla.co.uk/s3fs-public/styles/max_1300x1300/public/2018-03/Screen%20Shot%202018-03-11%20at%2010.09.27.png?itok=6899WDN7 1300w, https://assets.badzilla.co.uk/s3fs-public/styles/max_2600x2600/public/2018-03/Screen%20Shot%202018-03-11%20at%2010.09.27.png?itok=n1x2oYdn 1804w" sizes="(min-width: 1290px) 1290px, 100vw" src="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2018-03/Screen%20Shot%202018-03-11%20at%2010.09.27.png?itok=3UGeLQMw" alt="Successful Blog" typeof="foaf:Image" class="img-responsive" /&gt;


&lt;/div&gt;
          &lt;/div&gt;
  
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;&lt;p&gt;Ok so in the interim I fixed the missing Font Awesome library - not something I'd noticed before, but obviously it's been gitignored and it isn't in the composer.json file. Anyhoo the site is now fully functional and you can see from the URL bar I need to append the port :9090 as per my previous port forwarding fix. &lt;/p&gt;
&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Verdict&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;&lt;p&gt;Playing with ddev was an interesting experience, not without challenges, but ultimately rewarding. Here are some of the points I made as I went along. &lt;/p&gt;

&lt;ul&gt;
	&lt;li&gt;The &lt;em&gt;ddev exec &lt;/em&gt;command is run as root. This is a problem because it basically means using composer with it - such as &lt;em&gt;ddev exec composer update &lt;/em&gt;- would trash the file permissions of my codebase. Ownerships would become root, and that would lead to problems down the line. Composer should never be run as root. So the net effect is composer needs to be installed on the host system. Ideally I wanted a totally un-poluted filesystem without installing anything on the host beyond ddev. It also means since composer has a dependency on PHP, that needs to be installed, and now we have a system with different PHP CLI and FPM versions. &lt;/li&gt;
	&lt;li&gt;I couldn't get the &lt;em&gt;ddev import-db &lt;/em&gt;command to work. A minor inconvenience and of course it is easy to  use alternatives with the command line or drush. &lt;/li&gt;
	&lt;li&gt;Now I've got a working system - what next? I have a welter of phing targets to deploy my code, usually invoked by Jenkins. I could add phing at project level but how would I get Jenkins docker-ised up and running across all projects? I sense that could be tricky. &lt;/li&gt;
	&lt;li&gt;I can see ddev's value. I would place it in a small agency with both legacy D6 and D7 support projects alongside new D8 and WP builds. I can't see it as an enterprise solution - there is too much missing such as Memcache and the previously mentioned phing and Jenkins. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But all in all I really enjoyed my Saturday watching the football whilst playing with ddev and writing this blog - despite my teams losing! &lt;/p&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
          &lt;/div&gt;
  
      &lt;div class="field field--name-field-blog-youtube field--type-entity-reference-revisions field--label-hidden field--items"&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-text-youtube paragraph--view-mode--default"&gt;
          
      &lt;/div&gt;
&lt;/div&gt;
          &lt;/div&gt;
  
  &lt;div class="field field--name-field-blog-terms field--type-entity-reference field--label-inline"&gt;
    &lt;div class="field--label"&gt;blog terms&lt;/div&gt;
          &lt;span class="field__items"&gt;
              &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/drupal" hreflang="en"&gt;Drupal&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/drupal8" hreflang="en"&gt;Drupal 8&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/drupal7" hreflang="en"&gt;Drupal 7&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/drupal6" hreflang="en"&gt;Drupal 6&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/devops" hreflang="en"&gt;devops&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/docker" hreflang="en"&gt;Docker&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/virtualbox" hreflang="en"&gt;VirtualBox&lt;/a&gt;&lt;/span&gt;
              &lt;/span&gt;
      &lt;/div&gt;
</description>
  <pubDate>Sat, 10 Mar 2018 21:12:50 +0000</pubDate>
    <dc:creator>nigel</dc:creator>
    <guid isPermaLink="false">140 at http://badzilla.co.uk</guid>
    </item>
<item>
  <title>Recompiling PHP for serverless-php and Lambda</title>
  <link>http://badzilla.co.uk/recompiling-php-serverless-php-and-lambda</link>
  <description>
&lt;span&gt;Recompiling PHP for serverless-php and Lambda&lt;/span&gt;

&lt;span&gt;&lt;span lang="" about="http://badzilla.co.uk/user/1" typeof="schema:Person" property="schema:name" datatype="" xml:lang=""&gt;nigel&lt;/span&gt;&lt;/span&gt;

&lt;span&gt;Sun, 05/11/2017 - 15:54&lt;/span&gt;

      &lt;div class="field field--name-field-heading-image-text field--type-entity-reference-revisions field--label-hidden field--items"&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;&lt;p&gt;The serverless-php git repo contains a pre-compiled PHP executable which is uploaded to AWS Lambda as part of the FaaS deploy. However, and deliberately to keep it lightweight, many PHP extensions are not included in this PHP image. I thought I may get through my development without having to rebuild this image, but alas not! I decided to use the Twig template engine and that has a dependency on the &lt;em&gt;hash() &lt;/em&gt;function. I realised something was afoot when my execution failed.&lt;/p&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Cloudwatch error diagnostic&lt;/div&gt;
      
      &lt;div class="field field--name-field-blog-image field--type-image field--label-hidden field--items"&gt;
              &lt;div class="field--item"&gt;    &lt;img srcset="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2017-11/Screen%20Shot%202017-11-04%20at%2016.15.00.png?itok=U-oTFMYn 325w, https://assets.badzilla.co.uk/s3fs-public/styles/max_650x650/public/2017-11/Screen%20Shot%202017-11-04%20at%2016.15.00.png?itok=CgtqsJbq 650w, https://assets.badzilla.co.uk/s3fs-public/styles/max_1300x1300/public/2017-11/Screen%20Shot%202017-11-04%20at%2016.15.00.png?itok=9lFH1sA1 1300w, https://assets.badzilla.co.uk/s3fs-public/styles/max_2600x2600/public/2017-11/Screen%20Shot%202017-11-04%20at%2016.15.00.png?itok=1rPINsye 2600w" sizes="(min-width: 1290px) 1290px, 100vw" src="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2017-11/Screen%20Shot%202017-11-04%20at%2016.15.00.png?itok=U-oTFMYn" alt="Cloudwatch Error" typeof="foaf:Image" class="img-responsive" /&gt;


&lt;/div&gt;
          &lt;/div&gt;
  
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;The error was discovered by inspecting my Lambda function run log - you may be able to see able there is a uncaught exception leading to a fatal error.
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;Fatal error: Uncaught Error: Call to undefined &lt;span style="color: #000000; font-weight: bold;"&gt;function&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;hash&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;(&lt;/span&gt;&lt;span style="color: #7a0874; font-weight: bold;"&gt;)&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;in&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;var&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;task&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;vendor&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;twig&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;twig&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;lib&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;Twig&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;Environment.php:&lt;span style="color: #000000;"&gt;272&lt;/span&gt;&lt;span style="color: #ff0000;"&gt;"&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
I wasn't aware that hash() required a separate PHP extension, so I checked this on my local copy of PHP 7.1 on my Macbook with
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;$ php &lt;span style="color: #660033;"&gt;-m&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;|&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;grep&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;hash&lt;/span&gt;
&lt;span style="color: #7a0874; font-weight: bold;"&gt;hash&lt;/span&gt;
$ &lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
Aha! So nothing else for it, we need to add this to the compiled PHP image.&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Recompilation of PHP image&lt;/div&gt;
      
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;&lt;p&gt;Thankfully the serverless-php repo contains two files to aid the recompilation of the PHP image - &lt;em&gt;buildphp.sh &lt;/em&gt;which is a shell script to run the process, and &lt;em&gt;dockerfile.buildphp &lt;/em&gt;which is the configuration for a docker container in which the actual recompilation will occur. &lt;/p&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;The dockerfile contains the list of PHP extensions to include - so I added hash to the list
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;RUN .&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;configure \
    &lt;span style="color: #660033;"&gt;--enable-static&lt;/span&gt;=&lt;span style="color: #c20cb9; font-weight: bold;"&gt;yes&lt;/span&gt; \
    &lt;span style="color: #660033;"&gt;--enable-shared&lt;/span&gt;=no \
    &lt;span style="color: #660033;"&gt;--disable-all&lt;/span&gt; \
    &lt;span style="color: #660033;"&gt;--enable-json&lt;/span&gt; \
    &lt;span style="color: #660033;"&gt;--enable-libxml&lt;/span&gt; \
    &lt;span style="color: #660033;"&gt;--enable-mbstring&lt;/span&gt; \
    &lt;span style="color: #660033;"&gt;--enable-phar&lt;/span&gt; \
    &lt;span style="color: #660033;"&gt;--enable-soap&lt;/span&gt; \
    &lt;span style="color: #660033;"&gt;--enable-xml&lt;/span&gt; \
    &lt;span style="color: #660033;"&gt;--enable-hash&lt;/span&gt; \
    &lt;span style="color: #660033;"&gt;--with-curl&lt;/span&gt; \
    &lt;span style="color: #660033;"&gt;--with-gd&lt;/span&gt; \
    &lt;span style="color: #660033;"&gt;--with-zlib&lt;/span&gt; \
    &lt;span style="color: #660033;"&gt;--with-openssl&lt;/span&gt; \
    &lt;span style="color: #660033;"&gt;--without-pear&lt;/span&gt; \
    &lt;span style="color: #660033;"&gt;--enable-ctype&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
Now we need to check the PHP filesize and run the build script - most of the output of this has been cropped since it was copious.
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;$ &lt;span style="color: #c20cb9; font-weight: bold;"&gt;ls&lt;/span&gt; &lt;span style="color: #660033;"&gt;-las&lt;/span&gt; php
&lt;span style="color: #000000;"&gt;49144&lt;/span&gt; -rwxr-xr-x&lt;span style="color: #000000; font-weight: bold;"&gt;@&lt;/span&gt;  &lt;span style="color: #000000;"&gt;1&lt;/span&gt; nigel  staff  &lt;span style="color: #000000;"&gt;25161497&lt;/span&gt;  &lt;span style="color: #000000;"&gt;2&lt;/span&gt; Nov &lt;span style="color: #000000;"&gt;14&lt;/span&gt;:03 php
$ &lt;span style="color: #c20cb9; font-weight: bold;"&gt;chmod&lt;/span&gt; +x buildphp.sh 
$ .&lt;span style="color: #000000; font-weight: bold;"&gt;/&lt;/span&gt;buildphp.sh 
Build complete.
Don&lt;span style="color: #ff0000;"&gt;'t forget to run '&lt;/span&gt;&lt;span style="color: #c20cb9; font-weight: bold;"&gt;make&lt;/span&gt; &lt;span style="color: #7a0874; font-weight: bold;"&gt;test&lt;/span&gt;&lt;span style="color: #ff0000;"&gt;'.
 
 ---&gt; 7b602edcddb5
Removing intermediate container 6c3cd6936a6d
Successfully built 7b602edcddb5
Successfully tagged php-build:latest
2bdff18d52adad839b6cbdba9ee55e3263d5399326175827398f757cc9c74c44
$&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
Ok so let's check what we've got:
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;$ &lt;span style="color: #c20cb9; font-weight: bold;"&gt;ls&lt;/span&gt; &lt;span style="color: #660033;"&gt;-las&lt;/span&gt; php
&lt;span style="color: #000000;"&gt;50736&lt;/span&gt; &lt;span style="color: #660033;"&gt;-rwxr-xr-x&lt;/span&gt;  &lt;span style="color: #000000;"&gt;1&lt;/span&gt; nigel  staff  &lt;span style="color: #000000;"&gt;25976432&lt;/span&gt;  &lt;span style="color: #000000;"&gt;4&lt;/span&gt; Nov &lt;span style="color: #000000;"&gt;16&lt;/span&gt;:&lt;span style="color: #000000;"&gt;34&lt;/span&gt; php&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
A different size which is encouraging! Now let's deploy and run:
&lt;div class="geshifilter"&gt;&lt;div class="bash geshifilter-bash" style="font-family:monospace;"&gt;&lt;pre style="font-family: monospace; font-weight: normal; font-style: normal"&gt;&lt;span style="color: #666666;"&gt;$ &lt;/span&gt;sls deploy&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-heading-picture-text paragraph--view-mode--default"&gt;
          
            &lt;div class="field field--name-field-heading field--type-string field--label-hidden field--item"&gt;Results&lt;/div&gt;
      
      &lt;div class="field field--name-field-blog-image field--type-image field--label-hidden field--items"&gt;
              &lt;div class="field--item"&gt;    &lt;img srcset="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2017-11/APIGateway.png?itok=rLAiDdWm 325w, https://assets.badzilla.co.uk/s3fs-public/styles/max_650x650/public/2017-11/APIGateway.png?itok=GVCU_aLo 650w, https://assets.badzilla.co.uk/s3fs-public/styles/max_1300x1300/public/2017-11/APIGateway.png?itok=rAp7Ewbu 1300w, https://assets.badzilla.co.uk/s3fs-public/styles/max_2600x2600/public/2017-11/APIGateway.png?itok=T8fVQNnx 2600w" sizes="(min-width: 1290px) 1290px, 100vw" src="https://assets.badzilla.co.uk/s3fs-public/styles/max_325x325/public/2017-11/APIGateway.png?itok=rLAiDdWm" alt="API Gateway" typeof="foaf:Image" class="img-responsive" /&gt;


&lt;/div&gt;
          &lt;/div&gt;
  
            &lt;div class="field field--name-field-blog-text field--type-text-long field--label-hidden field--item"&gt;&lt;p&gt;If we now run our function from the API Gateway or point a web browser on our assigned URL we get a 200 success! Yey!&lt;/p&gt;&lt;/div&gt;
      
      &lt;/div&gt;
&lt;/div&gt;
          &lt;/div&gt;
  
      &lt;div class="field field--name-field-blog-youtube field--type-entity-reference-revisions field--label-hidden field--items"&gt;
              &lt;div class="field--item"&gt;  &lt;div class="paragraph paragraph--type--blog-text-youtube paragraph--view-mode--default"&gt;
          
      &lt;/div&gt;
&lt;/div&gt;
          &lt;/div&gt;
  
  &lt;div class="field field--name-field-blog-terms field--type-entity-reference field--label-inline"&gt;
    &lt;div class="field--label"&gt;blog terms&lt;/div&gt;
          &lt;span class="field__items"&gt;
              &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/php" hreflang="en"&gt;PHP&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/serverless-php" hreflang="en"&gt;serverless-php&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/serverless" hreflang="en"&gt;serverless&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/lambda" hreflang="en"&gt;lambda&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/docker" hreflang="en"&gt;Docker&lt;/a&gt;&lt;/span&gt;
          &lt;span class="field--item"&gt;&lt;a href="http://badzilla.co.uk/devops" hreflang="en"&gt;devops&lt;/a&gt;&lt;/span&gt;
              &lt;/span&gt;
      &lt;/div&gt;
</description>
  <pubDate>Sun, 05 Nov 2017 15:54:48 +0000</pubDate>
    <dc:creator>nigel</dc:creator>
    <guid isPermaLink="false">127 at http://badzilla.co.uk</guid>
    </item>

  </channel>
</rss>
