EC2 Support

This commit is contained in:
Defunct 2016-07-30 16:05:04 +00:00
parent 61401b2624
commit e0527d7d27
11 changed files with 1768 additions and 31 deletions

View file

@ -78,8 +78,10 @@
add_host:
name: "{{ do.droplet.ip_address }}"
groups: vpn-host
remote_user: root
ansible_python_interpreter: "/usr/bin/python2.7"
- name: Pause to let DigitalOcean boot up the VM
pause: seconds=180
- name: Wait for SSH to become available
wait_for: host={{ do.droplet.ip_address }} port=22 delay=60 timeout=320 state=started

View file

@ -1,27 +1,29 @@
# vim:ft=ansible:
---
- name: Common tools
hosts: vpn-host
remote_user: root
gather_facts: false
become: true
vars_files:
- config.cfg
pre_tasks:
- name: Install prerequisites.
raw: sudo apt-get update -qq && sudo apt-get install -qq -y python2.7
- name: Configure defaults.
raw: sudo update-alternatives --install /usr/bin/python python /usr/bin/python2.7 1
tasks:
- name: Wait for port 22 to become available
local_action: "wait_for port=22 host={{ inventory_hostname }}"
- name: Updating apt-get
raw: apt-get update -qq
- name: Install python2.7 for Ansible
raw: apt-get install -qq -y python2.7
- name: Gather Facts
setup:
- name: Install Updates, Patches and Additional Security Software
apt: upgrade=dist update_cache=yes
apt: update_cache=yes upgrade=dist
- name: Check if reboot is required
shell: >
@ -85,7 +87,20 @@
- name: Periodic upgrades configured
template: src=10periodic.j2 dest=/etc/apt/apt.conf.d/10periodic owner=root group=root mode=644
- hosts: 127.0.0.1
handlers:
- name: restart auditd
service: name=auditd state=restarted
- name: restart rsyslog
service: name=rsyslog state=restarted
- name: restart ssh
service: name=ssh state=restarted
- name: flush routing cache
shell: echo 1 > /proc/sys/net/ipv4/route/flush
- hosts: localhost
gather_facts: false
vars_files:
- config.cfg
@ -101,15 +116,3 @@
- "# and ensure that all your traffic passes through the VPN. #"
- "#----------------------------------------------------------------------#"
handlers:
- name: restart auditd
service: name=auditd state=restarted
- name: restart rsyslog
service: name=rsyslog state=restarted
- name: restart ssh
service: name=ssh state=restarted
- name: flush routing cache
shell: echo 1 > /proc/sys/net/ipv4/route/flush

View file

@ -1,6 +1,6 @@
---
- include: cloud.yml
- include: "{{ provider }}.yml"
- include: common.yml
- include: security.yml
- include: features.yml

187
ec2.ini Normal file
View file

@ -0,0 +1,187 @@
# Ansible EC2 external inventory script settings
#
[ec2]
# to talk to a private eucalyptus instance uncomment these lines
# and edit edit eucalyptus_host to be the host name of your cloud controller
#eucalyptus = True
#eucalyptus_host = clc.cloud.domain.org
# AWS regions to make calls to. Set this to 'all' to make request to all regions
# in AWS and merge the results together. Alternatively, set this to a comma
# separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2'
regions = us-east-1
#regions = all
regions_exclude = us-gov-west-1,cn-north-1,ap-south-1
# When generating inventory, Ansible needs to know how to address a server.
# Each EC2 instance has a lot of variables associated with it. Here is the list:
# http://docs.pythonboto.org/en/latest/ref/ec2.html#module-boto.ec2.instance
# Below are 2 variables that are used as the address of a server:
# - destination_variable
# - vpc_destination_variable
# This is the normal destination variable to use. If you are running Ansible
# from outside EC2, then 'public_dns_name' makes the most sense. If you are
# running Ansible from within EC2, then perhaps you want to use the internal
# address, and should set this to 'private_dns_name'. The key of an EC2 tag
# may optionally be used; however the boto instance variables hold precedence
# in the event of a collision.
destination_variable = public_dns_name
# This allows you to override the inventory_name with an ec2 variable, instead
# of using the destination_variable above. Addressing (aka ansible_ssh_host)
# will still use destination_variable. Tags should be written as 'tag_TAGNAME'.
#hostname_variable = tag_Name
# For server inside a VPC, using DNS names may not make sense. When an instance
# has 'subnet_id' set, this variable is used. If the subnet is public, setting
# this to 'ip_address' will return the public IP address. For instances in a
# private subnet, this should be set to 'private_ip_address', and Ansible must
# be run from within EC2. The key of an EC2 tag may optionally be used; however
# the boto instance variables hold precedence in the event of a collision.
# WARNING: - instances that are in the private vpc, _without_ public ip address
# will not be listed in the inventory until You set:
# vpc_destination_variable = private_ip_address
vpc_destination_variable = ip_address
# The following two settings allow flexible ansible host naming based on a
# python format string and a comma-separated list of ec2 tags. Note that:
#
# 1) If the tags referenced are not present for some instances, empty strings
# will be substituted in the format string.
# 2) This overrides both destination_variable and vpc_destination_variable.
#
#destination_format = {0}.{1}.example.com
#destination_format_tags = Name,environment
# To tag instances on EC2 with the resource records that point to them from
# Route53, uncomment and set 'route53' to True.
route53 = False
# To exclude RDS instances from the inventory, uncomment and set to False.
#rds = False
# To exclude ElastiCache instances from the inventory, uncomment and set to False.
#elasticache = False
# Additionally, you can specify the list of zones to exclude looking up in
# 'route53_excluded_zones' as a comma-separated list.
# route53_excluded_zones = samplezone1.com, samplezone2.com
# By default, only EC2 instances in the 'running' state are returned. Set
# 'all_instances' to True to return all instances regardless of state.
all_instances = False
# By default, only EC2 instances in the 'running' state are returned. Specify
# EC2 instance states to return as a comma-separated list. This
# option is overriden when 'all_instances' is True.
# instance_states = pending, running, shutting-down, terminated, stopping, stopped
# By default, only RDS instances in the 'available' state are returned. Set
# 'all_rds_instances' to True return all RDS instances regardless of state.
all_rds_instances = False
# By default, only ElastiCache clusters and nodes in the 'available' state
# are returned. Set 'all_elasticache_clusters' and/or 'all_elastic_nodes'
# to True return all ElastiCache clusters and nodes, regardless of state.
#
# Note that all_elasticache_nodes only applies to listed clusters. That means
# if you set all_elastic_clusters to false, no node will be return from
# unavailable clusters, regardless of the state and to what you set for
# all_elasticache_nodes.
all_elasticache_replication_groups = False
all_elasticache_clusters = False
all_elasticache_nodes = False
# API calls to EC2 are slow. For this reason, we cache the results of an API
# call. Set this to the path you want cache files to be written to. Two files
# will be written to this directory:
# - ansible-ec2.cache
# - ansible-ec2.index
cache_path = ~/.ansible/tmp
# The number of seconds a cache file is considered valid. After this many
# seconds, a new API call will be made, and the cache file will be updated.
# To disable the cache, set this value to 0
cache_max_age = 300
# Organize groups into a nested/hierarchy instead of a flat namespace.
nested_groups = False
# Replace - tags when creating groups to avoid issues with ansible
replace_dash_in_groups = True
# If set to true, any tag of the form "a,b,c" is expanded into a list
# and the results are used to create additional tag_* inventory groups.
expand_csv_tags = False
# The EC2 inventory output can become very large. To manage its size,
# configure which groups should be created.
group_by_instance_id = True
group_by_region = True
group_by_availability_zone = True
group_by_ami_id = True
group_by_instance_type = True
group_by_key_pair = True
group_by_vpc_id = True
group_by_security_group = True
group_by_tag_keys = True
group_by_tag_none = True
group_by_route53_names = True
group_by_rds_engine = True
group_by_rds_parameter_group = True
group_by_elasticache_engine = True
group_by_elasticache_cluster = True
group_by_elasticache_parameter_group = True
group_by_elasticache_replication_group = True
# If you only want to include hosts that match a certain regular expression
# pattern_include = staging-*
# If you want to exclude any hosts that match a certain regular expression
# pattern_exclude = staging-*
# Instance filters can be used to control which instances are retrieved for
# inventory. For the full list of possible filters, please read the EC2 API
# docs: http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeInstances.html#query-DescribeInstances-filters
# Filters are key/value pairs separated by '=', to list multiple filters use
# a list separated by commas. See examples below.
# Retrieve only instances with (key=value) env=staging tag
# instance_filters = tag:env=staging
# Retrieve only instances with role=webservers OR role=dbservers tag
# instance_filters = tag:role=webservers,tag:role=dbservers
# Retrieve only t1.micro instances OR instances with tag env=staging
# instance_filters = instance-type=t1.micro,tag:env=staging
# You can use wildcards in filter values also. Below will list instances which
# tag Name value matches webservers1*
# (ex. webservers15, webservers1a, webservers123 etc)
# instance_filters = tag:Name=webservers1*
# A boto configuration profile may be used to separate out credentials
# see http://boto.readthedocs.org/en/latest/boto_config_tut.html
# boto_profile = some-boto-profile-name
[credentials]
# The AWS credentials can optionally be specified here. Credentials specified
# here are ignored if the environment variable AWS_ACCESS_KEY_ID or
# AWS_PROFILE is set, or if the boto_profile property above is set.
#
# Supplying AWS credentials here is not recommended, as it introduces
# non-trivial security concerns. When going down this route, please make sure
# to set access permissions for this file correctly, e.g. handle it the same
# way as you would a private SSH key.
#
# Unlike the boto and AWS configure files, this section does not support
# profiles.
#
# aws_access_key_id = AXXXXXXXXXXXXXX
# aws_secret_access_key = XXXXXXXXXXXXXXXXXXX
# aws_security_token = XXXXXXXXXXXXXXXXXXXXXXXXXXXX

1429
ec2.py Executable file

File diff suppressed because it is too large Load diff

116
ec2.yml Normal file
View file

@ -0,0 +1,116 @@
# vim:ft=ansible:
- name: Create a sandbox instance
hosts: localhost
gather_facts: False
vars:
instance_type: t2.nano
security_group: vpn-secgroup
regions:
"1": "us-east-1"
"2": "us-west-1"
"3": "us-west-2"
"4": "ap-south-1"
"5": "ap-northeast-2"
"6": "ap-southeast-1"
"7": "ap-southeast-2"
"8": "ap-northeast-1"
"9": "eu-central-1"
"10": "eu-west-1"
"11": "sa-east-1"
vars_prompt:
- name: "region"
prompt: >
What region should the server be located in?
1. us-east-1 US East (N. Virginia)
2. us-west-1 US West (N. California)
3. us-west-2 US West (Oregon)
4. ap-south-1 Asia Pacific (Mumbai)
5. ap-northeast-2 Asia Pacific (Seoul)
6. ap-southeast-1 Asia Pacific (Singapore)
7. ap-southeast-2 Asia Pacific (Sydney)
8. ap-northeast-1 Asia Pacific (Tokyo)
9. eu-central-1 EU (Frankfurt)
10. eu-west-1 EU (Ireland)
11. sa-east-1 South America (São Paulo)
default: "1"
private: no
tasks:
- name: Grab the default interface subnet.
ec2_eni_facts:
region: "{{ regions[region] }}"
register: ec2_enis
- name: Locate official Ubuntu 16.04 AMI for region.
ec2_ami_find:
name: "ubuntu/images/hvm-ssd/ubuntu-xenial-16.04-amd64-server-*"
owner: 099720109477
sort: name
sort_order: descending
sort_end: 1
region: "{{ regions[region] }}"
register: ami_search
- set_fact:
ami_image: "{{ ami_search.results[0].ami_id }}"
default_subnet: "{{ ec2_enis.interfaces[0].subnet_id }}"
- name: Fetch our IP for security group.
ipify_facts:
- name: Add ssh public key.
ec2_key:
name: VPNKEY
region: "{{ regions[region] }}"
key_material: "{{ item }}"
with_file: ~/.ssh/id_rsa.pub
register: keypair
- name: Configure EC2 security group
ec2_group:
name: "{{ security_group }}"
description: Security group for VPN servers
region: "{{ regions[region] }}"
rules:
- proto: tcp
from_port: 443
to_port: 443
cidr_ip: 0.0.0.0/0
- proto: tcp
from_port: 22
to_port: 22
cidr_ip: "{{ ipify_public_ip }}/32"
rules_egress:
- proto: all
from_port: 0-65535
to_port: 0-65535
cidr_ip: 0.0.0.0/0
- name: Launch instance
ec2:
keypair: "VPNKEY"
group: "{{ security_group }}"
instance_type: "{{ instance_type }}"
image: "{{ ami_image }}"
wait: true
region: "{{ regions[region] }}"
vpc_subnet_id: "{{ default_subnet }}"
assign_public_ip: yes
instance_tags:
Name: VPN
register: ec2
- name: Add new instance to host group
add_host: hostname={{ item.public_ip }} groupname=vpn-host remote_user=ubuntu ansible_python_interpreter="/usr/bin/python2.7"
with_items: "{{ ec2.instances }}"
- name: Wait for SSH to come up
wait_for: host={{ item.public_dns_name }} port=22 delay=60 timeout=320 state=started
with_items: "{{ ec2.instances }}"
- name: accept new ssh fingerprints
shell: ssh-keyscan -H {{ item.public_ip }} >> ~/.ssh/known_hosts
with_items: "{{ ec2.instances }}"

View file

@ -3,7 +3,7 @@
- name: Other features
hosts: vpn-host
gather_facts: false
remote_user: root
become: true
vars_files:
- config.cfg

View file

@ -1,2 +1,2 @@
[localhost]
127.0.0.1 ansible_connection=local
localhost ansible_connection=local

View file

@ -2,7 +2,7 @@
- name: Security fixes
hosts: vpn-host
remote_user: root
become: true
vars_files:
- config.cfg
@ -131,4 +131,4 @@
- name: flush routing cache
shell: echo 1 > /proc/sys/net/ipv4/route/flush

View file

@ -3,7 +3,7 @@
- name: User management
hosts: user-management
gather_facts: false
remote_user: root
become: true
vars_files:
- config.cfg
@ -71,4 +71,4 @@
- name: Fetch server CA certificate
fetch: src=/{{ easyrsa_dir }}/easyrsa3/pki/ca.crt dest=configs/{{ server_name }}_ca.crt flat=yes

View file

@ -3,7 +3,7 @@
- name: VPN Configuration
hosts: vpn-host
gather_facts: false
remote_user: root
become: true
vars_files:
- config.cfg