forked from pinterest/mysql_utils
-
Notifications
You must be signed in to change notification settings - Fork 2
/
launch_amazon_mysql_server.py
executable file
·157 lines (134 loc) · 7.05 KB
/
launch_amazon_mysql_server.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#!/usr/bin/env python
import argparse
import inspect
import boto.ec2
import launch_replacement_db_host
from lib import mysql_lib
from lib import environment_specific
log = environment_specific.setup_logging_defaults(__name__)
def main():
parser = argparse.ArgumentParser()
parser.add_argument('--hostname',
required=True)
parser.add_argument('--instance_type',
choices=sorted(environment_specific.SUPPORTED_HARDWARE,
reverse=True),
required=True)
parser.add_argument('--vpc_security_group',
default=None,
choices=environment_specific.VPC_SECURITY_GROUPS.keys())
parser.add_argument('--availability_zone',
choices=environment_specific.SUPPORTED_AZ,
required=True)
parser.add_argument('--mysql_major_version',
choices=environment_specific.SUPPORTED_MYSQL_MAJOR_VERSIONS,
default=launch_replacement_db_host.DEFAULT_MYSQL_MAJOR_VERSION,
help='Default: {default}'.format(default=launch_replacement_db_host.DEFAULT_MYSQL_MAJOR_VERSION))
parser.add_argument('--mysql_minor_version',
choices=environment_specific.SUPPORTED_MYSQL_MINOR_VERSIONS,
default=launch_replacement_db_host.DEFAULT_MYSQL_MINOR_VERSION,
help='Default: {default}'.format(default=launch_replacement_db_host.DEFAULT_MYSQL_MINOR_VERSION))
parser.add_argument('--dry_run',
help=('Do not actually launch an instance, just show '
'the intended configuration'),
default=False,
action='store_true')
args = parser.parse_args()
launch_amazon_mysql_server(hostname=args.hostname,
instance_type=args.instance_type,
vpc_security_group=args.vpc_security_group,
availability_zone=args.availability_zone,
mysql_major_version=args.mysql_major_version,
mysql_minor_version=args.mysql_minor_version,
dry_run=args.dry_run)
def launch_amazon_mysql_server(hostname, instance_type, vpc_security_group,
availability_zone, mysql_major_version, mysql_minor_version,
dry_run, skip_name_check=False):
""" Launch a mysql server in aws
Args:
hostname - hostname of new server
instance_type - hardware type
vpc_security_group - VPC firewall rules.
availability_zone - AWS availability zone
mysql_major_version - MySQL major version. Example 5.5 or 5.6
mysql_minor_version - Which "branch" to use. Values are 'stable', 'staging'
and 'latest'.
dry_run - Do not actually launch a host, just show the expected config.
skip_name_check - Do not check if a hostname has already been used or log
usage. The assumption is the caller has already done this
Returns:
An amazon instance id.
"""
args, _, _, values = inspect.getargvalues(inspect.currentframe())
for param in args:
log.info("Requested {param} = {value}".format(param=param,
value=values[param]))
config = {'key_name': environment_specific.PEM_KEY,
'placement': availability_zone,
'instance_profile_name': environment_specific.INSTANCE_PROFILE_NAME,
'image_id': environment_specific.SUPPORTED_HARDWARE[instance_type]['ami'],
'instance_type': instance_type}
(subnet_name, config['subnet_id']) = get_subnet_from_sg(vpc_security_group,
availability_zone)
ssh_security = environment_specific.SSH_SECURITY_MAP[subnet_name]['ssh']
config['instance_profile_name'] = environment_specific.SSH_SECURITY_MAP[subnet_name]['iam']
config['security_group_ids'] = [environment_specific.VPC_SECURITY_GROUPS[vpc_security_group]]
hiera_config = environment_specific.HIERA_FORMAT.format(
ssh_security=ssh_security,
mysql_major_version=mysql_major_version.replace('.', ''),
mysql_minor_version=mysql_minor_version)
if hiera_config not in environment_specific.SUPPORTED_HIERA_CONFIGS:
raise Exception('Hiera config {hiera_config} is not supported.'
'Supported configs are: {supported}'
''.format(hiera_config=hiera_config,
supported=environment_specific.SUPPORTED_HIERA_CONFIGS))
config['user_data'] = ('#cloud-config\n'
'pinfo_team: {pinfo_team}\n'
'pinfo_env: {pinfo_env}\n'
'pinfo_role: {hiera_config}\n'
'hostname: {hostname}\n'
'raid: true\n'
'raid_fs: xfs\n'
'raid_mount: {raid_mount}'
''.format(pinfo_team=environment_specific.PINFO_TEAM,
pinfo_env=environment_specific.PINFO_ENV,
raid_mount=environment_specific.RAID_MOUNT,
hiera_config=hiera_config,
hostname=hostname))
log.info('Config for new server:\n{config}'.format(config=config))
conn = mysql_lib.get_mysqlops_connections()
if not skip_name_check and not launch_replacement_db_host.is_hostname_new(hostname, conn):
raise Exception('Hostname {hostname} has already been used!'
''.format(hostname=hostname))
if dry_run:
log.info('In dry run mode, returning now')
return
else:
conn = boto.ec2.connect_to_region(environment_specific.EC2_REGION)
instance_id = conn.run_instances(**config).instances[0].id
log.info('Launched instance {id}'.format(id=instance_id))
return instance_id
def get_subnet_from_sg(sg, az):
""" Given a VPC security group and a availiability zone
return a subnet
Args:
sg - A security group
az - An availibilty zone
Returns - An AWS subnet
"""
vpc_subnet = None
for entry in environment_specific.VPC_SUBNET_SG_MAP.keys():
if sg in environment_specific.VPC_SUBNET_SG_MAP[entry]:
vpc_subnet = entry
if not vpc_subnet:
raise Exception('Could not determine subnet for sg:{sg}'.format(sg=sg))
vpc_az_subnet = environment_specific.VPC_AZ_SUBNET_MAP[vpc_subnet][az]
log.info('Will use subnet "{vpc_az_subnet}" in "{vpc_subnet}" based upon '
'security group {sg} and availibility zone {az}'
''.format(vpc_az_subnet=vpc_az_subnet,
vpc_subnet=vpc_subnet,
sg=sg,
az=az))
return (vpc_subnet, vpc_az_subnet)
if __name__ == "__main__":
main()