add vpcaccess role
authorJustin Wind <j.wind@partner.samsung.com>
Mon, 13 Mar 2017 17:32:09 +0000 (10:32 -0700)
committerJustin Wind <j.wind@partner.samsung.com>
Mon, 13 Mar 2017 17:32:09 +0000 (10:32 -0700)
12 files changed:
init_vpcaccess.yml [new file with mode: 0644]
roles/vpcaccess-infrastructure/meta/main.yml [new file with mode: 0644]
roles/vpcaccess-infrastructure/tasks/main.yml [new file with mode: 0644]
roles/vpcaccess/files/ec2-pat.sh [new file with mode: 0644]
roles/vpcaccess/files/routeUpdater.py [new file with mode: 0644]
roles/vpcaccess/files/vpcaccess-policy.json [new file with mode: 0644]
roles/vpcaccess/handlers/main.yml [new file with mode: 0644]
roles/vpcaccess/meta/main.yml [new file with mode: 0644]
roles/vpcaccess/tasks/main.yml [new file with mode: 0644]
roles/vpcaccess/templates/ripd.conf.j2 [new file with mode: 0644]
roles/vpcaccess/templates/zebra.conf.j2 [new file with mode: 0644]
vpcaccess.yml [new file with mode: 0644]

diff --git a/init_vpcaccess.yml b/init_vpcaccess.yml
new file mode 100644 (file)
index 0000000..3b9d624
--- /dev/null
@@ -0,0 +1,7 @@
+---
+- hosts: localhost
+  connection: local
+  gather_facts: False
+  become: no
+  roles:
+  - vpcaccess-infrastructure
diff --git a/roles/vpcaccess-infrastructure/meta/main.yml b/roles/vpcaccess-infrastructure/meta/main.yml
new file mode 100644 (file)
index 0000000..492ebf1
--- /dev/null
@@ -0,0 +1,5 @@
+---
+dependencies:
+  - { role: aws-vpc }
+  - { role: aws-management-queues }
+  - { role: common-infrastructure }
diff --git a/roles/vpcaccess-infrastructure/tasks/main.yml b/roles/vpcaccess-infrastructure/tasks/main.yml
new file mode 100644 (file)
index 0000000..5149ad0
--- /dev/null
@@ -0,0 +1,93 @@
+---
+- 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
diff --git a/roles/vpcaccess/files/ec2-pat.sh b/roles/vpcaccess/files/ec2-pat.sh
new file mode 100644 (file)
index 0000000..6e119cc
--- /dev/null
@@ -0,0 +1,43 @@
+#!/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
diff --git a/roles/vpcaccess/files/routeUpdater.py b/roles/vpcaccess/files/routeUpdater.py
new file mode 100644 (file)
index 0000000..8901179
--- /dev/null
@@ -0,0 +1,64 @@
+#!/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)
+
+
diff --git a/roles/vpcaccess/files/vpcaccess-policy.json b/roles/vpcaccess/files/vpcaccess-policy.json
new file mode 100644 (file)
index 0000000..acd5795
--- /dev/null
@@ -0,0 +1,19 @@
+{
+       "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
diff --git a/roles/vpcaccess/handlers/main.yml b/roles/vpcaccess/handlers/main.yml
new file mode 100644 (file)
index 0000000..9c76715
--- /dev/null
@@ -0,0 +1,10 @@
+---
+- name: restart ripd
+  service:
+    name: ripd
+    state: restarted
+
+- name: restart zebra
+  service:
+    name: zebra
+    state: restarted
diff --git a/roles/vpcaccess/meta/main.yml b/roles/vpcaccess/meta/main.yml
new file mode 100644 (file)
index 0000000..96ecf5e
--- /dev/null
@@ -0,0 +1,3 @@
+---
+dependencies:
+  - { role: aws-vpc }
\ No newline at end of file
diff --git a/roles/vpcaccess/tasks/main.yml b/roles/vpcaccess/tasks/main.yml
new file mode 100644 (file)
index 0000000..10c394a
--- /dev/null
@@ -0,0 +1,90 @@
+---
+- 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
diff --git a/roles/vpcaccess/templates/ripd.conf.j2 b/roles/vpcaccess/templates/ripd.conf.j2
new file mode 100644 (file)
index 0000000..cfc5ac6
--- /dev/null
@@ -0,0 +1,25 @@
+! -*- 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
diff --git a/roles/vpcaccess/templates/zebra.conf.j2 b/roles/vpcaccess/templates/zebra.conf.j2
new file mode 100644 (file)
index 0000000..4e27500
--- /dev/null
@@ -0,0 +1,11 @@
+! -*- zebra -*-
+!
+! zebra configuration file
+!
+
+hostname {{ ansible_ec2_hostname }}
+password {{ QUAGGA_PASSWORD }}
+enable password {{ QUAGGA_PASSWORD }}
+
+interface tap0
+  description vpn interface
diff --git a/vpcaccess.yml b/vpcaccess.yml
new file mode 100644 (file)
index 0000000..1abeed9
--- /dev/null
@@ -0,0 +1,6 @@
+---
+- hosts: vpcaccess
+  become: true
+  roles:
+  - common
+  - vpcaccess