--- /dev/null
+---
+- hosts: localhost
+ connection: local
+ gather_facts: False
+ become: no
+ roles:
+ - vpcaccess-infrastructure
--- /dev/null
+---
+dependencies:
+ - { role: aws-vpc }
+ - { role: aws-management-queues }
+ - { role: common-infrastructure }
--- /dev/null
+---
+- assert:
+ that:
+ tags: ['check_vars']
+
+- name: vpcaccess iam
+ iam:
+ name: vpcaccess
+ iam_type: role
+ state: present
+
+- name: sg vpcaccess
+ ec2_group:
+ vpc_id: "{{ vpc.vpc.id }}"
+ region: "{{ vpc_region }}"
+ state: present
+ name: vpcaccess
+ description: "vpcaccess rules"
+ purge_rules: false
+ rules:
+ rules_egress:
+ - proto: all
+ cidr_ip: 0.0.0.0/0
+ register: sg_vpcaccess
+
+- name: vpcaccess lc
+ ec2_lc:
+ region: "{{ vpc_region }}"
+ name: vpcaccess-0000
+ image_id: "{{ DEFAULT_AMI }}"
+ key_name: "{{ MANAGEMENT_KEY_NAME }}"
+ instance_profile_name: vpcaccess
+ security_groups:
+ - "{{ sg_vpcaccess.group_id }}"
+ - "{{ sg_ssh.group_id }}"
+ instance_type: m4.large
+ volumes:
+# setting the root volume seems to prevent instances from launching
+# - device_name: /dev/sda1
+# volume_size: 8
+# volume_type: gp2
+# delete_on_termination: true
+ - device_name: /dev/sdb
+ ephemeral: ephemeral0
+ - device_name: /dev/sdc
+ ephemeral: ephemeral1
+ - device_name: /dev/sdd
+ ephemeral: ephemeral2
+ - device_name: /dev/sde
+ ephemeral: ephemeral3
+ register: vpcaccess_lc
+
+- name: suss out our subnets
+ ec2_vpc_subnet_facts:
+ region: "{{ vpc_region }}"
+ filters:
+ vpc_id: "{{ vpc.vpc.id }}"
+ "tag:zone": pub
+ register: public_subnet_ids
+
+- debug:
+ var: public_subnet_ids
+
+- name: vpcaccess asg
+ ec2_asg:
+ region: "{{ vpc_region }}"
+ name: vpcaccess
+ min_size: 1
+ max_size: 1
+ desired_capacity: 1
+ default_cooldown: 10
+ vpc_zone_identifier: "{{ public_subnet_ids.subnets|map(attribute='id')|list }}"
+ launch_config_name: "{{ vpcaccess_lc.name|default('checkmode') }}"
+ notification_topic: "{{ management_topic.sns_arn }}"
+ notification_types:
+ - autoscaling:EC2_INSTANCE_LAUNCH
+ load_balancers:
+ tags:
+ - account: "{{ ACCT_NAME }}"
+ propagate_at_launch: yes
+ - module: vpcaccess
+ propagate_at_launch: yes
+ - stack: ""
+ propagate_at_launch: yes
+ - country: ""
+ propagate_at_launch: yes
+ - phase: dev
+ propagate_at_launch: yes
+
+- name: not implemented yet
+ debug:
+ msg: |
+ attach policies to iam role
--- /dev/null
+#!/bin/bash
+
+# Configure the instance to run as a Port Address Translator (PAT) to provide
+# Internet connectivity to private instances.
+#
+
+IF='eth0'
+
+set -o pipefail
+
+function log(){
+ echo "$@" | /usr/bin/logger -t 'ec2-pat'
+}
+
+echo "Determining the MAC address on ${IF}"
+if ! IF_MAC=$(/sbin/ip address show dev ${IF} |
+ /bin/grep 'link/ether' |
+ /bin/awk '{print tolower($2)}')
+then
+ log "Unable to determine MAC address on eth0"
+ exit 1
+fi
+log "Found MAC: ${IF_MAC} on ${IF}"
+
+VPC_CIDR_URI="http://169.254.169.254/latest/meta-data/network/interfaces/macs/${IF_MAC}/vpc-ipv4-cidr-block"
+if ! VPC_CIDR_RANGE=$(/usr/bin/curl --retry 3 --retry-delay 1 --silent --fail "${VPC_CIDR_URI}")
+then
+ VPC_CIDR_RANGE="0.0.0.0/0"
+ log "Unable to retrive VPC CIDR range from meta-data. Using ${VPC_CIDR_RANGE} instead. PAT may not function correctly!"
+else
+ log "Retrived the VPC CIDR range: ${VPC_CIDR_RANGE} from meta-data"
+fi
+
+if ! /sbin/sysctl -w 'net.ipv4.ip_forward=1' &&
+ /sbin/sysctl -w "net.ipv4.conf.${IF}.send_redirects=0" &&
+ /sbin/iptables -t nat -A POSTROUTING -o ${IF} -s ${VPC_CIDR_RANGE} -j MASQUERADE
+then
+ log "Configuration of PAT failed"
+ exit 1
+fi
+
+log "Configuration of PAT complete"
+/sbin/iptables-save > /etc/sysconfig/iptables
--- /dev/null
+#!/usr/bin/python
+
+import boto.utils
+import boto.ec2
+import boto.vpc
+import sys
+
+dry_run = False
+
+# AWS access/secret keys
+aws_access = None
+aws_secret = None
+
+# Get all of the instance info e.g. curl 169.254.169.254/latest/meta-data/
+try:
+ instance_info = boto.utils.get_instance_metadata()
+except:
+ print "Could not get EC2 instance ID!"
+ sys.exit(1)
+
+instance_id = instance_info['instance-id']
+region_name = instance_info['placement']['availability-zone'][:-1]
+vpc_id = instance_info['network']['interfaces']['macs'][instance_info['mac']]['vpc-id']
+
+vpc_conn = boto.vpc.connect_to_region(region_name, aws_access_key_id=aws_access, aws_secret_access_key=aws_secret)
+ec2_conn = boto.ec2.connect_to_region(region_name, aws_access_key_id=aws_access, aws_secret_access_key=aws_secret)
+
+# Turn off Source/Destination checking if it's on
+source_dest_check = ec2_conn.get_instance_attribute(instance_id, 'sourceDestCheck')['sourceDestCheck']
+print "Source/Dest check: %s" % (source_dest_check,)
+
+if source_dest_check:
+ print "Instance must have source/dest checking disabled to NAT properly!"
+ try:
+ ec2_conn.modify_instance_attribute(instance_id, 'sourceDestCheck', False, dry_run=dry_run)
+ except Exception, e:
+ print "Could not modify source/dest check: %s" % (e,)
+ sys.exit(1)
+
+# Get the managed route tables for my VPC
+rt = vpc_conn.get_all_route_tables(filters={'vpc_id':vpc_id,'tag:managed':'yes'})
+
+# Just in case there's more than one
+for table in rt:
+ # See if there's a default route (0.0.0.0/0)
+ gw_route = next((route for route in table.routes if route.destination_cidr_block == '0.0.0.0/0'), None)
+ if not gw_route:
+ print "Could not find default gw route in routing table!"
+ else:
+ print "Found a gateway route: %s, %s, %s" % (table.id, gw_route.destination_cidr_block, instance_id)
+ try:
+ # If there is delete it, because I'm taking it over
+ vpc_conn.delete_route(table.id, '0.0.0.0/0', dry_run=dry_run)
+ except Exception, e:
+ print "Could not delete gw route! %s" % (e,)
+ sys.exit(1)
+ try:
+ # Make me the default route, I'm the router now!
+ vpc_conn.create_route(table.id, '0.0.0.0/0', instance_id=instance_id, dry_run=dry_run)
+ except Exception, e:
+ print "Could not replace gw route! %s" % (e,)
+ sys.exit(1)
+
+
--- /dev/null
+{
+ "Version": "2012-10-17",
+ "Statement": [
+ {
+ "Sid": "Stmt1489423268000",
+ "Effect": "Allow",
+ "Action": [
+ "ec2:AssociateAddress",
+ "ec2:CreateRoute",
+ "ec2:DeleteRoute",
+ "ec2:DescribeRouteTables",
+ "ec2:ModifyNetworkInterfaceAttribute"
+ ],
+ "Resource": [
+ "*"
+ ]
+ }
+ ]
+}
\ No newline at end of file
--- /dev/null
+---
+- name: restart ripd
+ service:
+ name: ripd
+ state: restarted
+
+- name: restart zebra
+ service:
+ name: zebra
+ state: restarted
--- /dev/null
+---
+dependencies:
+ - { role: aws-vpc }
\ No newline at end of file
--- /dev/null
+---
+- action: ec2_facts
+
+- name: Enable IP Forwarding
+ with_items:
+ - { "var": "net.ipv4.ip_forward", "val": 1 }
+ - { "var": "net.ipv4.conf.eth0.send_redirects", "val": 0 }
+ sysctl:
+ state: present
+ name: "{{ item.var }}"
+ value: "{{ item.val }}"
+ sysctl_set: yes
+ reload: yes
+ ignoreerrors: yes
+
+- name: naming things
+ set_fact:
+ environment_name: "{{ ACCT_NAME }}"
+- name: Find CIDR
+ set_fact:
+ subnet_to_announce: "{{ vpc.vpc.cidr_block }}"
+
+- name: enable PAT
+ iptables:
+ table: nat
+ chain: POSTROUTING
+ out_interface: eth0
+ source: "{{ vpc.vpc.cidr_block }}"
+ jump: MASQUERADE
+- command: /etc/init.d/iptables save
+ args:
+ creates: /etc/sysconfig/iptables
+
+- name: Attach EIP
+ delegate_to: localhost
+ become: no
+ ec2_eip:
+ state: present
+ in_vpc: true
+ device_id: "{{ ansible_ec2_instance_id }}"
+ region: "{{ ansible_ec2_placement_region }}"
+ reuse_existing_ip_allowed: yes
+ register: eip_attachment
+
+- name: Refresh inventory
+ when: eip_attachment|changed
+ meta: refresh_inventory
+
+- name: Install support scripts
+ with_items:
+ - routeUpdater.py
+ copy:
+ src: "{{ item }}"
+ dest: "/usr/local/bin/{{ item }}"
+ owner: root
+ group: root
+ mode: "0755"
+
+- name: Take over private VPC routing
+ command: /usr/local/bin/routeUpdater.py
+
+- name: Install Quagga
+ yum:
+ name: quagga
+ state: present
+
+- name: Configure Quagga
+ with_items:
+ - ripd.conf
+ - zebra.conf
+ template:
+ src: "{{ item }}.j2"
+ dest: "/etc/quagga/{{ item }}"
+ owner: quagga
+ group: quagga
+ mode: "0640"
+ notify:
+ - restart ripd
+ - restart zebra
+
+- name: Enable Quagga
+ with_items:
+ - ripd
+ - zebra
+ service:
+ name: "{{ item }}"
+ enabled: yes
+ notify:
+ - restart ripd
+ - restart zebra
--- /dev/null
+! -*- rip -*-
+!
+! RIPd configuration file
+!
+
+hostname {{ ansible_ec2_hostname }}
+password {{ QUAGGA_PASSWORD }}
+
+router rip
+ network tap0
+
+default-information originate
+route {{ subnet_to_announce }}
+
+version 2
+
+key chain {{ environment_name }}
+ key 1
+ key-string FVeKWpAUkTZPMZjyKXljIJy
+
+interface tap0
+ ip rip authentication mode md5
+ ip rip authentication key-chain {{ environment_name }}
+
+log stdout
--- /dev/null
+! -*- zebra -*-
+!
+! zebra configuration file
+!
+
+hostname {{ ansible_ec2_hostname }}
+password {{ QUAGGA_PASSWORD }}
+enable password {{ QUAGGA_PASSWORD }}
+
+interface tap0
+ description vpn interface
--- /dev/null
+---
+- hosts: vpcaccess
+ become: true
+ roles:
+ - common
+ - vpcaccess