mirror of
https://codeberg.org/scottslowe/learning-tools.git
synced 2026-03-11 09:04:37 +00:00
Merge pull request #111 from scottslowe/etcdv3
Add environment for creating an etcd v3 cluster on AWS
This commit is contained in:
commit
976227b442
19 changed files with 2264 additions and 0 deletions
5
etcd/etcdv3-ansible-aws-tf/.gitignore
vendored
Normal file
5
etcd/etcdv3-ansible-aws-tf/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
*.retry
|
||||
*.tfstate
|
||||
*.tfstate.backup
|
||||
*.tfvars
|
||||
ec2-tmp
|
||||
53
etcd/etcdv3-ansible-aws-tf/README.md
Normal file
53
etcd/etcdv3-ansible-aws-tf/README.md
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
# Running an etcd v3 Cluster on Ubuntu 16.04 on AWS
|
||||
|
||||
These files were created to allow users to use Terraform and Ansible to set up an etcd v3 cluster on AWS.
|
||||
|
||||
## Contents
|
||||
|
||||
* **ansible.cfg**: This configuration file supplies parameters for Ansible. No changes to this file should be necessary.
|
||||
|
||||
* **data.tf**: This Terraform file supplies some information needed by the overall Terraform configuration (AMI IDs, primarily). No changes to this file should be necessary.
|
||||
|
||||
* **ec2.ini**: This configuration file controls the EC2 dynamic inventory module for Ansible. The only change to this file would be specifying the AWS region you are using (if it is not "us-west-2").
|
||||
|
||||
* **ec2.py**: This is the EC2 dynamic inventory module used by Ansible.
|
||||
|
||||
* **etcd.conf.j2**: This Jinja2 template is used to create an environment file for configuring etcd. No changes to this file should be necessary.
|
||||
|
||||
* **etcd.service:** This is a systemd unit file for etcd. No changes to this file should be necessary.
|
||||
|
||||
* **etcd.yml**: This is the Ansible playbook that will configure the EC2 instances created by Terraform to run etcd. No changes to this file should be necessary.
|
||||
|
||||
* **main.tf**: This Terraform file calls two other Terraform modules (found in `modules/vpc` and `modules/instance-cluster`) to launch EC2 instances into a new VPC and configure them with security groups to allow etcd traffic. No changes to this file should be necessary.
|
||||
|
||||
* **provider.tf**: This Terraform file configures the AWS provider. No changes to this file should be necessary.
|
||||
|
||||
* **README.md**: This file you're currently reading.
|
||||
|
||||
* **variables.tf**: This Terraform file defines the variables that Terraform expects the user to provide (either via the command line or via a `*.tfvars` file). No changes to this file should be necessary.
|
||||
|
||||
## Instructions
|
||||
|
||||
These instructions assume that Terraform, Ansible, and the AWS CLI are already installed and working correctly.
|
||||
|
||||
1. Place the files from the `etcdv3-ansible-aws-tf` directory of this GitHub repository (the "lowescott/learning-tools" repository) into a directory on your system. You can clone the entire "learning-tools" repository (using `git clone`), or just download the specific files from the `etcdv3-ansible-aws-tf` directory.
|
||||
|
||||
2. Create a `terraform.tfvars` file that defines the "user_region", "node_type", and "key_pair" variables. If you skip this step, you must provide these variables via the command-line when running other `terraform` commands.
|
||||
|
||||
3. Run `terraform init` to load the modules and ensure that the AWS provider has been downloaded and is available.
|
||||
|
||||
4. Run `terraform plan` to plan what Terraform is going to do.
|
||||
|
||||
5. Run `terraform apply` to have Terraform create the specified infrastructure.
|
||||
|
||||
6. Run `ansible-playbook etcd.yml` to have Ansible configure the EC2 instances created by Terraform to run etcd.
|
||||
|
||||
7. Once step 6 has completed, You can test etcd by logging into one of the instances via SSH and running this command:
|
||||
|
||||
etcdctl member list
|
||||
|
||||
This should return a list of three nodes as members of the etcd cluster. If you receive an error or don't see all three VMs listed, tear down the environment with `terraform destroy` and recreate the environment from scratch. If you continue to experience problems, open an issue in the "learning-tools" repository on GitHub (or file a pull request fixing the problem).
|
||||
|
||||
8. When you're finished with the environment, run `terraform destroy` to tear everything down.
|
||||
|
||||
Enjoy!
|
||||
5
etcd/etcdv3-ansible-aws-tf/ansible.cfg
Normal file
5
etcd/etcdv3-ansible-aws-tf/ansible.cfg
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
[defaults]
|
||||
inventory = ./ec2.py
|
||||
private_key_file = ~/.ssh/aws_rsa
|
||||
remote_user = ubuntu
|
||||
host_key_checking = false
|
||||
19
etcd/etcdv3-ansible-aws-tf/data.tf
Normal file
19
etcd/etcdv3-ansible-aws-tf/data.tf
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
data "aws_ami" "node_ami" {
|
||||
most_recent = true
|
||||
owners = ["099720109477"]
|
||||
|
||||
filter {
|
||||
name = "name"
|
||||
values = ["*ubuntu-xenial-16.04*"]
|
||||
}
|
||||
|
||||
filter {
|
||||
name = "virtualization-type"
|
||||
values = ["hvm"]
|
||||
}
|
||||
|
||||
filter {
|
||||
name = "root-device-type"
|
||||
values = ["ebs"]
|
||||
}
|
||||
}
|
||||
209
etcd/etcdv3-ansible-aws-tf/ec2.ini
Normal file
209
etcd/etcdv3-ansible-aws-tf/ec2.ini
Normal file
|
|
@ -0,0 +1,209 @@
|
|||
# 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' and do not
|
||||
# provide the 'regions_exclude' option. If this is set to 'auto', AWS_REGION or
|
||||
# AWS_DEFAULT_REGION environment variable will be read to determine the region.
|
||||
regions = us-west-2
|
||||
#regions_exclude = us-gov-west-1, cn-north-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, set 'route53' to True.
|
||||
route53 = False
|
||||
|
||||
# To use Route53 records as the inventory hostnames, uncomment and set
|
||||
# to equal the domain name you wish to use. You must also have 'route53' (above)
|
||||
# set to True.
|
||||
# route53_hostnames = .example.com
|
||||
|
||||
# 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 overridden 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
|
||||
|
||||
# Include RDS cluster information (Aurora etc.)
|
||||
include_rds_clusters = 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 = ./ec2-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_aws_account = False
|
||||
group_by_ami_id = True
|
||||
group_by_instance_type = True
|
||||
group_by_instance_state = False
|
||||
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.
|
||||
|
||||
# If you want to apply multiple filters simultaneously, set stack_filters to
|
||||
# True. Default behaviour is to combine the results of all filters. Stacking
|
||||
# allows the use of multiple conditions to filter down, for example by
|
||||
# environment and type of host.
|
||||
stack_filters = False
|
||||
|
||||
# Retrieve only instances with (key=value) env=staging tag
|
||||
#instance_filters =
|
||||
|
||||
# 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*
|
||||
|
||||
# An IAM role can be assumed, so all requests are run as that role.
|
||||
# This can be useful for connecting across different accounts, or to limit user
|
||||
# access
|
||||
# iam_role = role-arn
|
||||
|
||||
# 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
|
||||
1587
etcd/etcdv3-ansible-aws-tf/ec2.py
Executable file
1587
etcd/etcdv3-ansible-aws-tf/ec2.py
Executable file
File diff suppressed because it is too large
Load diff
15
etcd/etcdv3-ansible-aws-tf/etcd.conf.j2
Normal file
15
etcd/etcdv3-ansible-aws-tf/etcd.conf.j2
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
ETCD_NAME="{{ hostvars[inventory_hostname]['ansible_hostname'] }}"
|
||||
ETCD_DATA_DIR="/var/etcd"
|
||||
ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379"
|
||||
ETCD_LISTEN_PEER_URLS="http://0.0.0.0:2380"
|
||||
ETCD_ADVERTISE_CLIENT_URLS="http://{{ hostvars[inventory_hostname]['ansible_eth0']['ipv4']['address'] }}:2379"
|
||||
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://{{ hostvars[inventory_hostname]['ansible_eth0']['ipv4']['address']}}:2380"
|
||||
ETCD_INITIAL_CLUSTER="{%- for host in groups['tag_role_etcd'] -%}
|
||||
{% if loop.last -%}
|
||||
{{ hostvars[host]['ansible_hostname'] }}=http://{{ hostvars[host]['ansible_eth0']['ipv4']['address'] }}:2380
|
||||
{%- else -%}
|
||||
{{ hostvars[host]['ansible_hostname'] }}=http://{{ hostvars[host]['ansible_eth0']['ipv4']['address'] }}:2380,
|
||||
{%- endif -%}
|
||||
{% endfor -%}"
|
||||
ETCD_INITIAL_CLUSTER_STATE="new"
|
||||
ETCD_INITIAL_CLUSTER_TOKEN="new-cluster"
|
||||
17
etcd/etcdv3-ansible-aws-tf/etcd.service
Normal file
17
etcd/etcdv3-ansible-aws-tf/etcd.service
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
[Unit]
|
||||
Description=etcd distributed key-value store
|
||||
Documentation=https://github.com/coreos/etcd
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=notify
|
||||
User=etcd
|
||||
WorkingDirectory=/var/etcd
|
||||
EnvironmentFile=-/etc/etcd/etcd.conf
|
||||
ExecStart=/usr/local/bin/etcd
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
LimitNOFILE=65536
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
107
etcd/etcdv3-ansible-aws-tf/etcd.yml
Normal file
107
etcd/etcdv3-ansible-aws-tf/etcd.yml
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
---
|
||||
- hosts: "all"
|
||||
become: true
|
||||
gather_facts: false
|
||||
|
||||
tasks:
|
||||
- name: "Install Python"
|
||||
raw: "apt-get -y -q install python"
|
||||
|
||||
- hosts: "tag_role_etcd"
|
||||
become: true
|
||||
vars:
|
||||
etcd_install_dir: "/usr/local/bin"
|
||||
etcd_platform: "linux-amd64"
|
||||
etcd_version: "3.2.18"
|
||||
etcd_name: "etcd-v{{etcd_version}}-{{etcd_platform}}"
|
||||
etcd_tgz: "{{etcd_name}}.tar.gz"
|
||||
etcd_tgz_url: "https://github.com/coreos/etcd/releases/download/v{{etcd_version}}/{{etcd_tgz}}"
|
||||
|
||||
tasks:
|
||||
- name: check for installation of etcd
|
||||
stat:
|
||||
path: '{{etcd_install_dir}}/{{etcd_name}}'
|
||||
changed_when: false
|
||||
register: etcd_binary_dir
|
||||
|
||||
- when: not etcd_binary_dir.stat.exists
|
||||
block:
|
||||
- name: download etcd
|
||||
become: yes
|
||||
become_user: root
|
||||
get_url:
|
||||
url: '{{etcd_tgz_url}}'
|
||||
dest: /tmp/{{etcd_tgz}}
|
||||
timeout: 300
|
||||
mode: 0644
|
||||
- name: unachive etcd
|
||||
become: yes
|
||||
become_user: root
|
||||
unarchive:
|
||||
remote_src: yes
|
||||
src: /tmp/{{etcd_tgz}}
|
||||
dest: '{{etcd_install_dir}}'
|
||||
creates: '{{etcd_install_dir}}/{{etcd_name}}'
|
||||
always:
|
||||
- name: delete archive
|
||||
become: yes
|
||||
become_user: root
|
||||
file:
|
||||
path: /tmp/{{etcd_tgz}}
|
||||
state: absent
|
||||
|
||||
- name: link etcd and etcdctl
|
||||
file:
|
||||
src: '{{etcd_install_dir}}/{{etcd_name}}/{{item}}'
|
||||
dest: '{{etcd_install_dir}}/{{item}}'
|
||||
state: link
|
||||
with_items:
|
||||
- etcd
|
||||
- etcdctl
|
||||
|
||||
- name: Create etcd group
|
||||
group:
|
||||
name: etcd
|
||||
state: present
|
||||
|
||||
- name: Create etcd user
|
||||
user:
|
||||
name: etcd
|
||||
create_home: no
|
||||
append: yes
|
||||
groups: etcd
|
||||
system: yes
|
||||
|
||||
- name: Create etcd directories
|
||||
file:
|
||||
path: "{{ item }}"
|
||||
state: directory
|
||||
owner: etcd
|
||||
group: etcd
|
||||
mode: 0755
|
||||
with_items:
|
||||
- /var/etcd
|
||||
- /etc/etcd
|
||||
|
||||
- name: Copy etcd systemd unit file
|
||||
copy:
|
||||
src: etcd.service
|
||||
dest: /etc/systemd/system/etcd.service
|
||||
owner: root
|
||||
group: root
|
||||
mode: 0755
|
||||
|
||||
- name: Render etcd.conf template
|
||||
template:
|
||||
src: etcd.conf.j2
|
||||
dest: /etc/etcd/etcd.conf
|
||||
|
||||
- name: Reload systemd
|
||||
systemd:
|
||||
daemon_reload: yes
|
||||
|
||||
- name: Enable etcd service
|
||||
systemd:
|
||||
name: etcd
|
||||
enabled: true
|
||||
state: started
|
||||
65
etcd/etcdv3-ansible-aws-tf/main.tf
Normal file
65
etcd/etcdv3-ansible-aws-tf/main.tf
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
module "etcd-vpc" {
|
||||
source = "./modules/vpc"
|
||||
|
||||
name = "etcd"
|
||||
vpc_cidr_block = "10.200.0.0/16"
|
||||
vpc_dns_hostnames = "true"
|
||||
vpc_dns_support = "true"
|
||||
subnet_map_pub_ip = "true"
|
||||
}
|
||||
|
||||
resource "aws_security_group" "etcd_sg" {
|
||||
name = "etcd_sg"
|
||||
description = "Allow traffic needed by etcd"
|
||||
vpc_id = "${module.etcd-vpc.vpc_id}"
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "etcd_sg_allow_sg_in" {
|
||||
security_group_id = "${aws_security_group.etcd_sg.id}"
|
||||
type = "ingress"
|
||||
from_port = 0
|
||||
to_port = 0
|
||||
protocol = "-1"
|
||||
source_security_group_id = "${aws_security_group.etcd_sg.id}"
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "etcd_sg_allow_sg_out" {
|
||||
security_group_id = "${aws_security_group.etcd_sg.id}"
|
||||
type = "egress"
|
||||
from_port = 0
|
||||
to_port = 0
|
||||
protocol = "-1"
|
||||
source_security_group_id = "${aws_security_group.etcd_sg.id}"
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "etcd_sg_allow_client" {
|
||||
security_group_id = "${aws_security_group.etcd_sg.id}"
|
||||
type = "ingress"
|
||||
from_port = 2379
|
||||
to_port = 2379
|
||||
protocol = "tcp"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "etcd_sg_allow_peer" {
|
||||
security_group_id = "${aws_security_group.etcd_sg.id}"
|
||||
type = "ingress"
|
||||
from_port = 2380
|
||||
to_port = 2380
|
||||
protocol = "tcp"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
}
|
||||
|
||||
module "etcd" {
|
||||
source = "./modules/instance-cluster"
|
||||
|
||||
name = "etcd"
|
||||
ami = "${data.aws_ami.node_ami.id}"
|
||||
type = "${var.node_type}"
|
||||
assign_pub_ip = true
|
||||
ssh_key = "${var.key_pair}"
|
||||
cluster_size = 3
|
||||
subnet_list = ["${module.etcd-vpc.subnet_id}"]
|
||||
sec_group_list = ["${module.etcd-vpc.default_sg_id}", "${aws_security_group.etcd_sg.id}"]
|
||||
role = "etcd"
|
||||
}
|
||||
15
etcd/etcdv3-ansible-aws-tf/modules/instance-cluster/main.tf
Normal file
15
etcd/etcdv3-ansible-aws-tf/modules/instance-cluster/main.tf
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
# Launch a cluster of instances
|
||||
resource "aws_instance" "instance" {
|
||||
count = "${var.cluster_size}"
|
||||
ami = "${var.ami}"
|
||||
instance_type = "${var.type}"
|
||||
subnet_id = "${element(var.subnet_list, count.index)}"
|
||||
key_name = "${var.ssh_key}"
|
||||
associate_public_ip_address = "${var.assign_pub_ip}"
|
||||
vpc_security_group_ids = ["${var.sec_group_list}"]
|
||||
|
||||
tags {
|
||||
Name = "${var.name}-${count.index}"
|
||||
role = "${var.role}"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
output "cluster_instance_public_addresses" {
|
||||
value = "${aws_instance.instance.*.public_ip}"
|
||||
}
|
||||
|
||||
output "cluster_instance_private_addresses" {
|
||||
value = "${aws_instance.instance.*.private_ip}"
|
||||
}
|
||||
|
||||
output "cluster_instance_ids" {
|
||||
value = "${aws_instance.instance.*.id}"
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
variable "name" {
|
||||
type = "string"
|
||||
description = "Name to use for instances in this instance cluster"
|
||||
}
|
||||
|
||||
variable "ami" {
|
||||
type = "string"
|
||||
description = "AMI to use for instances in this instance cluster"
|
||||
}
|
||||
|
||||
variable "type" {
|
||||
type = "string"
|
||||
description = "Type to use for instances in this instance cluster"
|
||||
}
|
||||
|
||||
variable "assign_pub_ip" {
|
||||
type = "string"
|
||||
description = "True/False to assign a public IP address"
|
||||
}
|
||||
|
||||
variable "ssh_key" {
|
||||
type = "string"
|
||||
description = "SSH key to inject into instances in this instance cluster"
|
||||
}
|
||||
|
||||
variable "cluster_size" {
|
||||
type = "string"
|
||||
description = "Number of instances in this instance cluster"
|
||||
}
|
||||
|
||||
variable "subnet_list" {
|
||||
type = "list"
|
||||
description = "List of subnet IDs where to launch instances"
|
||||
}
|
||||
|
||||
variable "sec_group_list" {
|
||||
type = "list"
|
||||
description = "List of security group IDs for instances to use"
|
||||
}
|
||||
|
||||
variable "role" {
|
||||
type = "string"
|
||||
description = "Value to assign to the Role tag on instances"
|
||||
}
|
||||
3
etcd/etcdv3-ansible-aws-tf/modules/vpc/data.tf
Normal file
3
etcd/etcdv3-ansible-aws-tf/modules/vpc/data.tf
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
data "aws_availability_zones" "az_list" {
|
||||
state = "available"
|
||||
}
|
||||
52
etcd/etcdv3-ansible-aws-tf/modules/vpc/main.tf
Normal file
52
etcd/etcdv3-ansible-aws-tf/modules/vpc/main.tf
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
# Create a new VPC
|
||||
resource "aws_vpc" "vpc" {
|
||||
cidr_block = "${var.vpc_cidr_block}"
|
||||
enable_dns_hostnames = "${var.vpc_dns_hostnames}"
|
||||
enable_dns_support = "${var.vpc_dns_support}"
|
||||
|
||||
tags {
|
||||
Name = "${var.name}_vpc"
|
||||
tool = "terraform"
|
||||
}
|
||||
}
|
||||
|
||||
# Modify default VPC security group to allow inbound SSH
|
||||
resource "aws_security_group_rule" "allow_ssh" {
|
||||
type = "ingress"
|
||||
from_port = 22
|
||||
to_port = 22
|
||||
protocol = "tcp"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
security_group_id = "${aws_vpc.vpc.default_security_group_id}"
|
||||
}
|
||||
|
||||
# Create a new Internet gateway
|
||||
resource "aws_internet_gateway" "gateway" {
|
||||
vpc_id = "${aws_vpc.vpc.id}"
|
||||
|
||||
tags {
|
||||
Name = "${var.name}_igw"
|
||||
tool = "terraform"
|
||||
}
|
||||
}
|
||||
|
||||
# Add default route to VPC's main route table
|
||||
resource "aws_route" "default_route" {
|
||||
route_table_id = "${aws_vpc.vpc.main_route_table_id}"
|
||||
destination_cidr_block = "0.0.0.0/0"
|
||||
gateway_id = "${aws_internet_gateway.gateway.id}"
|
||||
}
|
||||
|
||||
# Create a public subnet in the new VPC
|
||||
resource "aws_subnet" "subnet" {
|
||||
count = "${length(data.aws_availability_zones.az_list.names)}"
|
||||
vpc_id = "${aws_vpc.vpc.id}"
|
||||
cidr_block = "${cidrsubnet(var.vpc_cidr_block, 4, count.index)}"
|
||||
availability_zone = "${element(data.aws_availability_zones.az_list.names, count.index)}"
|
||||
map_public_ip_on_launch = "${var.subnet_map_pub_ip}"
|
||||
|
||||
tags {
|
||||
Name = "${var.name}_subnet_${count.index}"
|
||||
tool = "terraform"
|
||||
}
|
||||
}
|
||||
15
etcd/etcdv3-ansible-aws-tf/modules/vpc/output.tf
Normal file
15
etcd/etcdv3-ansible-aws-tf/modules/vpc/output.tf
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
output "vpc_id" {
|
||||
value = "${aws_vpc.vpc.id}"
|
||||
}
|
||||
|
||||
output "subnet_id" {
|
||||
value = "${aws_subnet.subnet.*.id}"
|
||||
}
|
||||
|
||||
output "subnet_az" {
|
||||
value = "${aws_subnet.subnet.*.availability_zone}"
|
||||
}
|
||||
|
||||
output "default_sg_id" {
|
||||
value = "${aws_vpc.vpc.default_security_group_id}"
|
||||
}
|
||||
24
etcd/etcdv3-ansible-aws-tf/modules/vpc/variables.tf
Normal file
24
etcd/etcdv3-ansible-aws-tf/modules/vpc/variables.tf
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
variable "name" {
|
||||
type = "string"
|
||||
description = "Name prefix to use for networking resources"
|
||||
}
|
||||
|
||||
variable "vpc_cidr_block" {
|
||||
type = "string"
|
||||
description = "CIDR block to use for new VPC"
|
||||
}
|
||||
|
||||
variable "vpc_dns_hostnames" {
|
||||
type = "string"
|
||||
description = "True/False to enable DNS hostnames in new VPC"
|
||||
}
|
||||
|
||||
variable "vpc_dns_support" {
|
||||
type = "string"
|
||||
description = "True/False to enable DNS support in new VPC"
|
||||
}
|
||||
|
||||
variable "subnet_map_pub_ip" {
|
||||
type = "string"
|
||||
description = "True/False to map public IP addresses on launch"
|
||||
}
|
||||
4
etcd/etcdv3-ansible-aws-tf/provider.tf
Normal file
4
etcd/etcdv3-ansible-aws-tf/provider.tf
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
provider "aws" {
|
||||
region = "${var.user_region}"
|
||||
version = "~> 1.15"
|
||||
}
|
||||
14
etcd/etcdv3-ansible-aws-tf/variables.tf
Normal file
14
etcd/etcdv3-ansible-aws-tf/variables.tf
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
variable "user_region" {
|
||||
type = "string"
|
||||
description = "AWS region to use for all resources"
|
||||
}
|
||||
|
||||
variable "node_type" {
|
||||
type = "string"
|
||||
description = "Type of instance to use, such as t2.large"
|
||||
}
|
||||
|
||||
variable "key_pair" {
|
||||
type = "string"
|
||||
description = "SSH keypair to use for accessing instances"
|
||||
}
|
||||
Loading…
Reference in a new issue