Introduction

This project provides a simple example of using tools traditionally used for software development and applying them in the context of networking. The objective is to provide an environment where changes can be made across your IT environment in an agile manner, where your network’s configuration changes operational status is automatically evaluated and changes orchestrated between various networking and software componants.

This project uses the following tools:

  • Github Actions
  • Ansible
  • Meraki MX Appliance
  • AWS EC2 instance

The project shall configure IPSec based connectivty between a Meraki MX appliance and an Amazon EC2 instance (via an AWS Virtual Gateway in the VPC). The connectivity shall be firewalled at the MX end, the configuration of which shall be controlled as part of the repo. Changes to the repo (specifically, the "config.yml" and "playbook.yaml" files) shall automatically trigger the following Github Actions:

  • lint the repo
  • push the configuration changes out
  • carry out a simple connectivity test using ping

The key reasons to control networks in this manner is to enable:

  • Automate testing such as syntax checking / linting
  • Tracking
    • Who made changes and when
    • Differences in configurations
    • State at points in time
  • Rollback failed changes
  • Integrate the control of software changes with the control of the network upon which they rely

Tools overview

Github Actions

GitHub Actions help you automate tasks within your development life cycle. GitHub Actions are event-driven, meaning that you can run a series of commands after a specified event has occurred. In this project, we'll be triggering Actions when somebody pushes an update to our configuration files ("config.yaml" or "playbook.yml"). This event will trigger the actions defined in ".github/workflows/main.yml". The key operations Githib Actions takes are:

  • Starts our Actions Job with the runner - this is a Github hosted server, we're using Ubuntu. The runner exectures our steps:
  • checks-out our repo - this enables our workflow to access it
  • lints our ansible playbook - checks playbooks for practices and behavior that could potentially be improved
  • executes the bash script defined at sh ./scripts/entrypoint.sh. It also passes to the script a number of "secrets" - these are defined under the repo Settings -> Secrets

Bash Script

  • the script defined at ./scripts/entrypoint.sh sets up our runner's server enviroinment - installing the AWS Python SDK (boto3/botocore). Once this has completed it launces our Ansible Playbook ('playbook.yml'), and passes it the environment variables that we passed above.
  • Our Ansible Playbook walks through a number of steps that gathers configuration information from both the Meraki and AWS EC2 environments (via API calls to both services), and uses this information to create an IPSec tunnel from a Meraki MX appliance, to an AWS Virtual Gateway. This includes creating the relevant routing at both ends, and creating a firewall configuration at the Meraki side, the rules for which are defined in "playbooks/config.yaml"

Connectivity test

  • At this point we should have connectivity from our MX Appliance to the AWS EC2 instance. We can carry out a simple connectivoty test by launcing a ping from our EC2 instance to the public IP of the MX appliance. This uses the AWS Systems Manager Agent (SSM Agent). After a short pause for the command to execute, we use SSM again to recover the result.
  • All steps above can be monitored using the 'Actions' tab. The image below shows a successful ping to the external MX address at the "aws ssm get-command-invocation" job:
    Diagram

Usage

To use this workflow, simply fork this repo and configure for your own environment using the "config.yml" file and the Secrets (described below).

Operation

The high level operation of the Github Actions are described in the diagram below:

Diagram

Secrets

Confidential details such as API keys should be passed to your Actions Workflow via the 'Secrets' function. This is accessible via Settings->Secrets and should be configured as follows:

Diagram

The secrets are updated as shown below, in this example the Meraki API key.

Diagram

Once the Secrets are configured, they are passed to our workflow and into our Ansible Playbook via environment variables. The following extract from "main.yml" shows the secrets being passed to "entrypoint.sh" as environement variables:

Diagram

Within "entrypoint.sh", the secrets are futher passed to ansible as we launch the playbook, with the following command:

ansible-playbook playbook.yml --extra-vars "MERAKI_API_KEY=$MERAKI_API_KEY AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY PSK=$PSK RTID=$RTID AWS_REGION=$AWS_REGION AWS_GATEWAY_ID=$AWS_GATEWAY_ID"

The format of the secrets is as follows:

Secret Format notes
AWS_ACCESS_KEY_ID 208ZW1NH6X4G6ZRH62C3
AWS_GATEWAY_ID vgw-7nulnyegucu9q3692h0d Virtual Private Gateway
AWS_REGION eu-west-1
AWS_SECRET_ACCESS_KEY BhdcqNDnvCnqcaSb4bjnspwDzb8Rv2keu7+CMytB
INSTANCE_IDS i-0a4j05i2hf5020wxke AWS EC2 Instance ID
MERAKIAPI 400d1de3f36caed4bdb91b7cbaba1950f0d7827d Meraki Dashboard API key
PSK VH19rDeWT_wne543217nx3mri8g4sv6Q Preshared key for IPSec Tunnel
RTID rtb-fb6f1234 AWS Route Table ID

Requirements and Assumptions

Meraki

Assumptions

The solution has been tested with a simple Meraki network consisting of:

  • Any MX Security Appliance.
  • A single MX appliance
  • A single uplink to the Internnet
  • A single local subnet

API Key

Open your Meraki dashboard: https://dashboard.meraki.com
Once logged in, navigate to the Organization Settings menu.
Ensure that the API Access is set to “Enable access to the Cisco Meraki Dashboard API”

Diagram

Amazon Web Services

Assumptions

It is assumed that the AWS serivce is a simple on with:

Diagram

API Key and configuration details

Diagram

AWS_REGION is selected at the top right hand side. In the screenshot above this is selected as 'Ohio', which translates to 'us-east-2' in the drop down menu. EC2/VPCs using the 'Ohio' region should populate AWS_REGION with 'us-east-2'.

  • INSTANCE_IDS
    is the EC2 instance ID, found under the 'EC2->Instances" menu:

Diagram

  • AWS_GATEWAY_ID (="Internet Gateway") and RTID (=Route Table ID") can be found in the VPC Service section

Diagram

Other

  • PSK - the Preshared key used in the IPSec Tunnel can be generated at random.

Use Case

# Introduction This project provides a simple example of using tools traditionally used for software development and applying them in the context of networking. The objective is to provide an environment where changes can be made across your IT environment in an agile manner, where your network’s configuration changes operational status is automatically evaluated and changes orchestrated between various networking and software componants. This project uses the following tools: * Github Actions * Ansible * Meraki MX Appliance * AWS EC2 instance The project shall configure IPSec based connectivty between a Meraki MX appliance and an Amazon EC2 instance (via an AWS Virtual Gateway in the VPC). The connectivity shall be firewalled at the MX end, the configuration of which shall be controlled as part of the repo. Changes to the repo (specifically, the "config.yml" and "playbook.yaml" files) shall automatically trigger the following Github Actions: * lint the repo * push the configuration changes out * carry out a simple connectivity test using ping The key reasons to control networks in this manner is to enable: * Automate testing such as syntax checking / linting * Tracking * Who made changes and when * Differences in configurations * State at points in time * Rollback failed changes * Integrate the control of software changes with the control of the network upon which they rely # Tools overview ## Github Actions GitHub Actions help you automate tasks within your development life cycle. GitHub Actions are event-driven, meaning that you can run a series of commands after a specified event has occurred. In this project, we'll be triggering Actions when somebody pushes an update to our configuration files ("config.yaml" or "playbook.yml"). This event will trigger the actions defined in ".github/workflows/main.yml". The key operations Githib Actions takes are: * Starts our Actions Job with the runner - this is a Github hosted server, we're using Ubuntu. The runner exectures our steps: * checks-out our repo - this enables our workflow to access it * lints our ansible playbook - checks playbooks for practices and behavior that could potentially be improved * executes the bash script defined at sh ./scripts/entrypoint.sh. It also passes to the script a number of "secrets" - these are defined under the repo Settings -> Secrets ### Bash Script * the script defined at ./scripts/entrypoint.sh sets up our runner's server enviroinment - installing the AWS Python SDK (boto3/botocore). Once this has completed it launces our Ansible Playbook ('playbook.yml'), and passes it the environment variables that we passed above. * Our Ansible Playbook walks through a number of steps that gathers configuration information from both the Meraki and AWS EC2 environments (via API calls to both services), and uses this information to create an IPSec tunnel from a Meraki MX appliance, to an AWS Virtual Gateway. This includes creating the relevant routing at both ends, and creating a firewall configuration at the Meraki side, the rules for which are defined in "playbooks/config.yaml" ### Connectivity test * At this point we should have connectivity from our MX Appliance to the AWS EC2 instance. We can carry out a simple connectivoty test by launcing a ping from our EC2 instance to the public IP of the MX appliance. This uses the AWS Systems Manager Agent (SSM Agent). After a short pause for the command to execute, we use SSM again to recover the result. * All steps above can be monitored using the 'Actions' tab. The image below shows a successful ping to the external MX address at the "aws ssm get-command-invocation" job: ![Diagram](Images/Actions.png) # Usage To use this workflow, simply fork this repo and configure for your own environment using the "config.yml" file and the Secrets (described below). # Operation The high level operation of the Github Actions are described in the diagram below: ![Diagram](Images/HighLevel.png) ## Secrets Confidential details such as API keys should be passed to your Actions Workflow via the 'Secrets' function. This is accessible via Settings->Secrets and should be configured as follows: ![Diagram](Images/Secrets.png) The secrets are updated as shown below, in this example the Meraki API key. ![Diagram](Images/Secrets2.png) Once the Secrets are configured, they are passed to our workflow and into our Ansible Playbook via environment variables. The following extract from "main.yml" shows the secrets being passed to "entrypoint.sh" as environement variables: ![Diagram](Images/envar.png) Within "entrypoint.sh", the secrets are futher passed to ansible as we launch the playbook, with the following command: ansible-playbook playbook.yml --extra-vars "MERAKI_API_KEY=$MERAKI_API_KEY AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY PSK=$PSK RTID=$RTID AWS_REGION=$AWS_REGION AWS_GATEWAY_ID=$AWS_GATEWAY_ID" The format of the secrets is as follows: Secret| Format | notes ------------ | ------------- | ------------------- AWS_ACCESS_KEY_ID | 208ZW1NH6X4G6ZRH62C3 | AWS_GATEWAY_ID | vgw-7nulnyegucu9q3692h0d | Virtual Private Gateway AWS_REGION | eu-west-1 | AWS_SECRET_ACCESS_KEY | BhdcqNDnvCnqcaSb4bjnspwDzb8Rv2keu7+CMytB| INSTANCE_IDS | i-0a4j05i2hf5020wxke | AWS EC2 Instance ID MERAKIAPI | 400d1de3f36caed4bdb91b7cbaba1950f0d7827d | Meraki Dashboard API key PSK | VH19rDeWT_wne543217nx3mri8g4sv6Q | Preshared key for IPSec Tunnel RTID | rtb-fb6f1234 | AWS Route Table ID ## Requirements and Assumptions ### Meraki #### Assumptions The solution has been tested with a simple Meraki network consisting of: * Any MX Security Appliance. * A single MX appliance * A single uplink to the Internnet * A single local subnet #### API Key * Instructions for generating a Meraki Dashboard API key: https://developer.cisco.com/meraki/build/meraki-postman-collection-getting-started/ Open your Meraki dashboard: https://dashboard.meraki.com Once logged in, navigate to the Organization Settings menu. Ensure that the API Access is set to “Enable access to the Cisco Meraki Dashboard API” ![Diagram](Images/api.png) ### Amazon Web Services #### Assumptions It is assumed that the AWS serivce is a simple on with: * Single VPC * Single Route Table * Single Virtual Gatewy * Security Group used permits ICMP traffic * Single EC2 instance running, with SSM agent installed. SSM comes preinstalled in some Amazon Machine Images https://docs.aws.amazon.com/systems-manager/latest/userguide/ssm-agent.html SSM is automatically installed when launching an Ubuntu server: ![Diagram](Images/ubuntu.png) #### API Key and configuration details * AWS Access Key and Secret Access Key can be found by signing into your AWS console as an IAM user, then navigate to your user name in the upper right section of the navigation bar. From the drop-down menu, select My Security Credentials, as shown in Figure: https://aws.amazon.com/blogs/security/how-to-find-update-access-keys-password-mfa-aws-management-console/ ![Diagram](Images/awscred.png) AWS_REGION is selected at the top right hand side. In the screenshot above this is selected as 'Ohio', which translates to 'us-east-2' in the drop down menu. EC2/VPCs using the 'Ohio' region should populate AWS_REGION with 'us-east-2'. * INSTANCE_IDS is the EC2 instance ID, found under the 'EC2->Instances" menu: ![Diagram](Images/EC2.png) * AWS_GATEWAY_ID (="Internet Gateway") and RTID (=Route Table ID") can be found in the VPC Service section ![Diagram](Images/VPC.png) ### Other * PSK - the Preshared key used in the IPSec Tunnel can be generated at random.
View code on GitHub
  • Owner

  • Contributors

    +2Github contributors
  • Categories

  • Products

    Meraki
  • Programming Languages

    Shell
  • License

    Other

Code Exchange Community

Get help, share code, and collaborate with other developers in the Code Exchange community.View Community
Disclaimer:
Cisco provides Code Exchange for convenience and informational purposes only, with no support of any kind. This page contains information and links from third-party websites that are governed by their own separate terms. Reference to a project or contributor on this page does not imply any affiliation with or endorsement by Cisco.