Mercurial > public > mercurial-scm > hg-stable
annotate contrib/automation/hgautomation/aws.py @ 42305:8dc22a209420
automation: wait for instance profiles and roles
Otherwise there is a race condition between creating the resources
and us attempting to use them / them becoming available.
The role waiter API was recently introduced, so we had to upgrade
the boto3 package to get it. Other packages were also updated
to latest versions just because.
Even with this change, I still run into issues with the IAM instance
profile not being available when we attempt to create an EC2 instance
using a just-created profile. I'm not sure what's going on. Possibly
a bug on Amazon's end. But the new behavior is "more correct."
Differential Revision: https://phab.mercurial-scm.org/D6286
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Sat, 27 Apr 2019 11:38:58 -0700 |
parents | dd6a9723ae2b |
children | e570106beda1 |
rev | line source |
---|---|
42024
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
1 # aws.py - Automation code for Amazon Web Services |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
2 # |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
3 # Copyright 2019 Gregory Szorc <gregory.szorc@gmail.com> |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
4 # |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
5 # This software may be used and distributed according to the terms of the |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
6 # GNU General Public License version 2 or any later version. |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
7 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
8 # no-check-code because Python 3 native. |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
9 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
10 import contextlib |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
11 import copy |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
12 import hashlib |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
13 import json |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
14 import os |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
15 import pathlib |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
16 import subprocess |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
17 import time |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
18 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
19 import boto3 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
20 import botocore.exceptions |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
21 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
22 from .winrm import ( |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
23 run_powershell, |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
24 wait_for_winrm, |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
25 ) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
26 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
27 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
28 SOURCE_ROOT = pathlib.Path(os.path.abspath(__file__)).parent.parent.parent.parent |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
29 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
30 INSTALL_WINDOWS_DEPENDENCIES = (SOURCE_ROOT / 'contrib' / |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
31 'install-windows-dependencies.ps1') |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
32 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
33 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
34 KEY_PAIRS = { |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
35 'automation', |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
36 } |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
37 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
38 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
39 SECURITY_GROUPS = { |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
40 'windows-dev-1': { |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
41 'description': 'Mercurial Windows instances that perform build automation', |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
42 'ingress': [ |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
43 { |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
44 'FromPort': 22, |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
45 'ToPort': 22, |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
46 'IpProtocol': 'tcp', |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
47 'IpRanges': [ |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
48 { |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
49 'CidrIp': '0.0.0.0/0', |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
50 'Description': 'SSH from entire Internet', |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
51 }, |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
52 ], |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
53 }, |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
54 { |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
55 'FromPort': 3389, |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
56 'ToPort': 3389, |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
57 'IpProtocol': 'tcp', |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
58 'IpRanges': [ |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
59 { |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
60 'CidrIp': '0.0.0.0/0', |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
61 'Description': 'RDP from entire Internet', |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
62 }, |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
63 ], |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
64 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
65 }, |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
66 { |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
67 'FromPort': 5985, |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
68 'ToPort': 5986, |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
69 'IpProtocol': 'tcp', |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
70 'IpRanges': [ |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
71 { |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
72 'CidrIp': '0.0.0.0/0', |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
73 'Description': 'PowerShell Remoting (Windows Remote Management)', |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
74 }, |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
75 ], |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
76 } |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
77 ], |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
78 }, |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
79 } |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
80 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
81 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
82 IAM_ROLES = { |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
83 'ephemeral-ec2-role-1': { |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
84 'description': 'Mercurial temporary EC2 instances', |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
85 'policy_arns': [ |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
86 'arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforSSM', |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
87 ], |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
88 }, |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
89 } |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
90 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
91 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
92 ASSUME_ROLE_POLICY_DOCUMENT = ''' |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
93 { |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
94 "Version": "2012-10-17", |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
95 "Statement": [ |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
96 { |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
97 "Effect": "Allow", |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
98 "Principal": { |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
99 "Service": "ec2.amazonaws.com" |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
100 }, |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
101 "Action": "sts:AssumeRole" |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
102 } |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
103 ] |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
104 } |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
105 '''.strip() |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
106 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
107 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
108 IAM_INSTANCE_PROFILES = { |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
109 'ephemeral-ec2-1': { |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
110 'roles': [ |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
111 'ephemeral-ec2-role-1', |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
112 ], |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
113 } |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
114 } |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
115 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
116 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
117 # User Data for Windows EC2 instance. Mainly used to set the password |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
118 # and configure WinRM. |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
119 # Inspired by the User Data script used by Packer |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
120 # (from https://www.packer.io/intro/getting-started/build-image.html). |
42064
0e9066db5e44
automation: use raw strings when there are backslashes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
42024
diff
changeset
|
121 WINDOWS_USER_DATA = r''' |
42024
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
122 <powershell> |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
123 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
124 # TODO enable this once we figure out what is failing. |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
125 #$ErrorActionPreference = "stop" |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
126 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
127 # Set administrator password |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
128 net user Administrator "%s" |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
129 wmic useraccount where "name='Administrator'" set PasswordExpires=FALSE |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
130 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
131 # First, make sure WinRM can't be connected to |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
132 netsh advfirewall firewall set rule name="Windows Remote Management (HTTP-In)" new enable=yes action=block |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
133 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
134 # Delete any existing WinRM listeners |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
135 winrm delete winrm/config/listener?Address=*+Transport=HTTP 2>$Null |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
136 winrm delete winrm/config/listener?Address=*+Transport=HTTPS 2>$Null |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
137 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
138 # Create a new WinRM listener and configure |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
139 winrm create winrm/config/listener?Address=*+Transport=HTTP |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
140 winrm set winrm/config/winrs '@{MaxMemoryPerShellMB="0"}' |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
141 winrm set winrm/config '@{MaxTimeoutms="7200000"}' |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
142 winrm set winrm/config/service '@{AllowUnencrypted="true"}' |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
143 winrm set winrm/config/service '@{MaxConcurrentOperationsPerUser="12000"}' |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
144 winrm set winrm/config/service/auth '@{Basic="true"}' |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
145 winrm set winrm/config/client/auth '@{Basic="true"}' |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
146 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
147 # Configure UAC to allow privilege elevation in remote shells |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
148 $Key = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System' |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
149 $Setting = 'LocalAccountTokenFilterPolicy' |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
150 Set-ItemProperty -Path $Key -Name $Setting -Value 1 -Force |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
151 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
152 # Configure and restart the WinRM Service; Enable the required firewall exception |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
153 Stop-Service -Name WinRM |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
154 Set-Service -Name WinRM -StartupType Automatic |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
155 netsh advfirewall firewall set rule name="Windows Remote Management (HTTP-In)" new action=allow localip=any remoteip=any |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
156 Start-Service -Name WinRM |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
157 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
158 # Disable firewall on private network interfaces so prompts don't appear. |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
159 Set-NetFirewallProfile -Name private -Enabled false |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
160 </powershell> |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
161 '''.lstrip() |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
162 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
163 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
164 WINDOWS_BOOTSTRAP_POWERSHELL = ''' |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
165 Write-Output "installing PowerShell dependencies" |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
166 Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
167 Set-PSRepository -Name PSGallery -InstallationPolicy Trusted |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
168 Install-Module -Name OpenSSHUtils -RequiredVersion 0.0.2.0 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
169 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
170 Write-Output "installing OpenSSL server" |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
171 Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
172 # Various tools will attempt to use older versions of .NET. So we enable |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
173 # the feature that provides them so it doesn't have to be auto-enabled |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
174 # later. |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
175 Write-Output "enabling .NET Framework feature" |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
176 Install-WindowsFeature -Name Net-Framework-Core |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
177 ''' |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
178 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
179 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
180 class AWSConnection: |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
181 """Manages the state of a connection with AWS.""" |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
182 |
42304
dd6a9723ae2b
automation: don't create resources when deleting things
Gregory Szorc <gregory.szorc@gmail.com>
parents:
42303
diff
changeset
|
183 def __init__(self, automation, region: str, ensure_ec2_state: bool=True): |
42024
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
184 self.automation = automation |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
185 self.local_state_path = automation.state_path |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
186 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
187 self.prefix = 'hg-' |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
188 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
189 self.session = boto3.session.Session(region_name=region) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
190 self.ec2client = self.session.client('ec2') |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
191 self.ec2resource = self.session.resource('ec2') |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
192 self.iamclient = self.session.client('iam') |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
193 self.iamresource = self.session.resource('iam') |
42304
dd6a9723ae2b
automation: don't create resources when deleting things
Gregory Szorc <gregory.szorc@gmail.com>
parents:
42303
diff
changeset
|
194 self.security_groups = {} |
42024
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
195 |
42304
dd6a9723ae2b
automation: don't create resources when deleting things
Gregory Szorc <gregory.szorc@gmail.com>
parents:
42303
diff
changeset
|
196 if ensure_ec2_state: |
dd6a9723ae2b
automation: don't create resources when deleting things
Gregory Szorc <gregory.szorc@gmail.com>
parents:
42303
diff
changeset
|
197 ensure_key_pairs(automation.state_path, self.ec2resource) |
dd6a9723ae2b
automation: don't create resources when deleting things
Gregory Szorc <gregory.szorc@gmail.com>
parents:
42303
diff
changeset
|
198 self.security_groups = ensure_security_groups(self.ec2resource) |
42305
8dc22a209420
automation: wait for instance profiles and roles
Gregory Szorc <gregory.szorc@gmail.com>
parents:
42304
diff
changeset
|
199 ensure_iam_state(self.iamclient, self.iamresource) |
42024
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
200 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
201 def key_pair_path_private(self, name): |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
202 """Path to a key pair private key file.""" |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
203 return self.local_state_path / 'keys' / ('keypair-%s' % name) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
204 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
205 def key_pair_path_public(self, name): |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
206 return self.local_state_path / 'keys' / ('keypair-%s.pub' % name) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
207 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
208 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
209 def rsa_key_fingerprint(p: pathlib.Path): |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
210 """Compute the fingerprint of an RSA private key.""" |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
211 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
212 # TODO use rsa package. |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
213 res = subprocess.run( |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
214 ['openssl', 'pkcs8', '-in', str(p), '-nocrypt', '-topk8', |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
215 '-outform', 'DER'], |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
216 capture_output=True, |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
217 check=True) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
218 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
219 sha1 = hashlib.sha1(res.stdout).hexdigest() |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
220 return ':'.join(a + b for a, b in zip(sha1[::2], sha1[1::2])) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
221 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
222 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
223 def ensure_key_pairs(state_path: pathlib.Path, ec2resource, prefix='hg-'): |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
224 remote_existing = {} |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
225 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
226 for kpi in ec2resource.key_pairs.all(): |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
227 if kpi.name.startswith(prefix): |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
228 remote_existing[kpi.name[len(prefix):]] = kpi.key_fingerprint |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
229 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
230 # Validate that we have these keys locally. |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
231 key_path = state_path / 'keys' |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
232 key_path.mkdir(exist_ok=True, mode=0o700) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
233 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
234 def remove_remote(name): |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
235 print('deleting key pair %s' % name) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
236 key = ec2resource.KeyPair(name) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
237 key.delete() |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
238 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
239 def remove_local(name): |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
240 pub_full = key_path / ('keypair-%s.pub' % name) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
241 priv_full = key_path / ('keypair-%s' % name) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
242 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
243 print('removing %s' % pub_full) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
244 pub_full.unlink() |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
245 print('removing %s' % priv_full) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
246 priv_full.unlink() |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
247 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
248 local_existing = {} |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
249 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
250 for f in sorted(os.listdir(key_path)): |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
251 if not f.startswith('keypair-') or not f.endswith('.pub'): |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
252 continue |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
253 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
254 name = f[len('keypair-'):-len('.pub')] |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
255 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
256 pub_full = key_path / f |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
257 priv_full = key_path / ('keypair-%s' % name) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
258 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
259 with open(pub_full, 'r', encoding='ascii') as fh: |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
260 data = fh.read() |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
261 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
262 if not data.startswith('ssh-rsa '): |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
263 print('unexpected format for key pair file: %s; removing' % |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
264 pub_full) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
265 pub_full.unlink() |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
266 priv_full.unlink() |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
267 continue |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
268 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
269 local_existing[name] = rsa_key_fingerprint(priv_full) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
270 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
271 for name in sorted(set(remote_existing) | set(local_existing)): |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
272 if name not in local_existing: |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
273 actual = '%s%s' % (prefix, name) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
274 print('remote key %s does not exist locally' % name) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
275 remove_remote(actual) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
276 del remote_existing[name] |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
277 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
278 elif name not in remote_existing: |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
279 print('local key %s does not exist remotely' % name) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
280 remove_local(name) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
281 del local_existing[name] |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
282 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
283 elif remote_existing[name] != local_existing[name]: |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
284 print('key fingerprint mismatch for %s; ' |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
285 'removing from local and remote' % name) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
286 remove_local(name) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
287 remove_remote('%s%s' % (prefix, name)) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
288 del local_existing[name] |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
289 del remote_existing[name] |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
290 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
291 missing = KEY_PAIRS - set(remote_existing) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
292 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
293 for name in sorted(missing): |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
294 actual = '%s%s' % (prefix, name) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
295 print('creating key pair %s' % actual) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
296 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
297 priv_full = key_path / ('keypair-%s' % name) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
298 pub_full = key_path / ('keypair-%s.pub' % name) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
299 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
300 kp = ec2resource.create_key_pair(KeyName=actual) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
301 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
302 with priv_full.open('w', encoding='ascii') as fh: |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
303 fh.write(kp.key_material) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
304 fh.write('\n') |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
305 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
306 priv_full.chmod(0o0600) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
307 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
308 # SSH public key can be extracted via `ssh-keygen`. |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
309 with pub_full.open('w', encoding='ascii') as fh: |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
310 subprocess.run( |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
311 ['ssh-keygen', '-y', '-f', str(priv_full)], |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
312 stdout=fh, |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
313 check=True) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
314 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
315 pub_full.chmod(0o0600) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
316 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
317 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
318 def delete_instance_profile(profile): |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
319 for role in profile.roles: |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
320 print('removing role %s from instance profile %s' % (role.name, |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
321 profile.name)) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
322 profile.remove_role(RoleName=role.name) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
323 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
324 print('deleting instance profile %s' % profile.name) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
325 profile.delete() |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
326 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
327 |
42305
8dc22a209420
automation: wait for instance profiles and roles
Gregory Szorc <gregory.szorc@gmail.com>
parents:
42304
diff
changeset
|
328 def ensure_iam_state(iamclient, iamresource, prefix='hg-'): |
42024
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
329 """Ensure IAM state is in sync with our canonical definition.""" |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
330 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
331 remote_profiles = {} |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
332 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
333 for profile in iamresource.instance_profiles.all(): |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
334 if profile.name.startswith(prefix): |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
335 remote_profiles[profile.name[len(prefix):]] = profile |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
336 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
337 for name in sorted(set(remote_profiles) - set(IAM_INSTANCE_PROFILES)): |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
338 delete_instance_profile(remote_profiles[name]) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
339 del remote_profiles[name] |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
340 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
341 remote_roles = {} |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
342 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
343 for role in iamresource.roles.all(): |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
344 if role.name.startswith(prefix): |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
345 remote_roles[role.name[len(prefix):]] = role |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
346 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
347 for name in sorted(set(remote_roles) - set(IAM_ROLES)): |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
348 role = remote_roles[name] |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
349 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
350 print('removing role %s' % role.name) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
351 role.delete() |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
352 del remote_roles[name] |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
353 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
354 # We've purged remote state that doesn't belong. Create missing |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
355 # instance profiles and roles. |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
356 for name in sorted(set(IAM_INSTANCE_PROFILES) - set(remote_profiles)): |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
357 actual = '%s%s' % (prefix, name) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
358 print('creating IAM instance profile %s' % actual) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
359 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
360 profile = iamresource.create_instance_profile( |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
361 InstanceProfileName=actual) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
362 remote_profiles[name] = profile |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
363 |
42305
8dc22a209420
automation: wait for instance profiles and roles
Gregory Szorc <gregory.szorc@gmail.com>
parents:
42304
diff
changeset
|
364 waiter = iamclient.get_waiter('instance_profile_exists') |
8dc22a209420
automation: wait for instance profiles and roles
Gregory Szorc <gregory.szorc@gmail.com>
parents:
42304
diff
changeset
|
365 waiter.wait(InstanceProfileName=actual) |
8dc22a209420
automation: wait for instance profiles and roles
Gregory Szorc <gregory.szorc@gmail.com>
parents:
42304
diff
changeset
|
366 print('IAM instance profile %s is available' % actual) |
8dc22a209420
automation: wait for instance profiles and roles
Gregory Szorc <gregory.szorc@gmail.com>
parents:
42304
diff
changeset
|
367 |
42024
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
368 for name in sorted(set(IAM_ROLES) - set(remote_roles)): |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
369 entry = IAM_ROLES[name] |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
370 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
371 actual = '%s%s' % (prefix, name) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
372 print('creating IAM role %s' % actual) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
373 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
374 role = iamresource.create_role( |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
375 RoleName=actual, |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
376 Description=entry['description'], |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
377 AssumeRolePolicyDocument=ASSUME_ROLE_POLICY_DOCUMENT, |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
378 ) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
379 |
42305
8dc22a209420
automation: wait for instance profiles and roles
Gregory Szorc <gregory.szorc@gmail.com>
parents:
42304
diff
changeset
|
380 waiter = iamclient.get_waiter('role_exists') |
8dc22a209420
automation: wait for instance profiles and roles
Gregory Szorc <gregory.szorc@gmail.com>
parents:
42304
diff
changeset
|
381 waiter.wait(RoleName=actual) |
8dc22a209420
automation: wait for instance profiles and roles
Gregory Szorc <gregory.szorc@gmail.com>
parents:
42304
diff
changeset
|
382 print('IAM role %s is available' % actual) |
8dc22a209420
automation: wait for instance profiles and roles
Gregory Szorc <gregory.szorc@gmail.com>
parents:
42304
diff
changeset
|
383 |
42024
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
384 remote_roles[name] = role |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
385 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
386 for arn in entry['policy_arns']: |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
387 print('attaching policy %s to %s' % (arn, role.name)) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
388 role.attach_policy(PolicyArn=arn) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
389 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
390 # Now reconcile state of profiles. |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
391 for name, meta in sorted(IAM_INSTANCE_PROFILES.items()): |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
392 profile = remote_profiles[name] |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
393 wanted = {'%s%s' % (prefix, role) for role in meta['roles']} |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
394 have = {role.name for role in profile.roles} |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
395 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
396 for role in sorted(have - wanted): |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
397 print('removing role %s from %s' % (role, profile.name)) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
398 profile.remove_role(RoleName=role) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
399 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
400 for role in sorted(wanted - have): |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
401 print('adding role %s to %s' % (role, profile.name)) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
402 profile.add_role(RoleName=role) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
403 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
404 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
405 def find_windows_server_2019_image(ec2resource): |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
406 """Find the Amazon published Windows Server 2019 base image.""" |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
407 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
408 images = ec2resource.images.filter( |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
409 Filters=[ |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
410 { |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
411 'Name': 'owner-alias', |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
412 'Values': ['amazon'], |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
413 }, |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
414 { |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
415 'Name': 'state', |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
416 'Values': ['available'], |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
417 }, |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
418 { |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
419 'Name': 'image-type', |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
420 'Values': ['machine'], |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
421 }, |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
422 { |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
423 'Name': 'name', |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
424 'Values': ['Windows_Server-2019-English-Full-Base-2019.02.13'], |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
425 }, |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
426 ]) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
427 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
428 for image in images: |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
429 return image |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
430 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
431 raise Exception('unable to find Windows Server 2019 image') |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
432 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
433 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
434 def ensure_security_groups(ec2resource, prefix='hg-'): |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
435 """Ensure all necessary Mercurial security groups are present. |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
436 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
437 All security groups are prefixed with ``hg-`` by default. Any security |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
438 groups having this prefix but aren't in our list are deleted. |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
439 """ |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
440 existing = {} |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
441 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
442 for group in ec2resource.security_groups.all(): |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
443 if group.group_name.startswith(prefix): |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
444 existing[group.group_name[len(prefix):]] = group |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
445 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
446 purge = set(existing) - set(SECURITY_GROUPS) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
447 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
448 for name in sorted(purge): |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
449 group = existing[name] |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
450 print('removing legacy security group: %s' % group.group_name) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
451 group.delete() |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
452 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
453 security_groups = {} |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
454 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
455 for name, group in sorted(SECURITY_GROUPS.items()): |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
456 if name in existing: |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
457 security_groups[name] = existing[name] |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
458 continue |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
459 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
460 actual = '%s%s' % (prefix, name) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
461 print('adding security group %s' % actual) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
462 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
463 group_res = ec2resource.create_security_group( |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
464 Description=group['description'], |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
465 GroupName=actual, |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
466 ) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
467 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
468 group_res.authorize_ingress( |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
469 IpPermissions=group['ingress'], |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
470 ) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
471 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
472 security_groups[name] = group_res |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
473 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
474 return security_groups |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
475 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
476 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
477 def terminate_ec2_instances(ec2resource, prefix='hg-'): |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
478 """Terminate all EC2 instances managed by us.""" |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
479 waiting = [] |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
480 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
481 for instance in ec2resource.instances.all(): |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
482 if instance.state['Name'] == 'terminated': |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
483 continue |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
484 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
485 for tag in instance.tags or []: |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
486 if tag['Key'] == 'Name' and tag['Value'].startswith(prefix): |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
487 print('terminating %s' % instance.id) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
488 instance.terminate() |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
489 waiting.append(instance) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
490 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
491 for instance in waiting: |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
492 instance.wait_until_terminated() |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
493 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
494 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
495 def remove_resources(c, prefix='hg-'): |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
496 """Purge all of our resources in this EC2 region.""" |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
497 ec2resource = c.ec2resource |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
498 iamresource = c.iamresource |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
499 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
500 terminate_ec2_instances(ec2resource, prefix=prefix) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
501 |
42302
730edbd836d8
automation: only iterate over our AMIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
42064
diff
changeset
|
502 for image in ec2resource.images.filter(Owners=['self']): |
42024
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
503 if image.name.startswith(prefix): |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
504 remove_ami(ec2resource, image) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
505 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
506 for group in ec2resource.security_groups.all(): |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
507 if group.group_name.startswith(prefix): |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
508 print('removing security group %s' % group.group_name) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
509 group.delete() |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
510 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
511 for profile in iamresource.instance_profiles.all(): |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
512 if profile.name.startswith(prefix): |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
513 delete_instance_profile(profile) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
514 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
515 for role in iamresource.roles.all(): |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
516 if role.name.startswith(prefix): |
42303
fcb97cb91ff8
automation: detach policies before deleting role
Gregory Szorc <gregory.szorc@gmail.com>
parents:
42302
diff
changeset
|
517 for p in role.attached_policies.all(): |
fcb97cb91ff8
automation: detach policies before deleting role
Gregory Szorc <gregory.szorc@gmail.com>
parents:
42302
diff
changeset
|
518 print('detaching policy %s from %s' % (p.arn, role.name)) |
fcb97cb91ff8
automation: detach policies before deleting role
Gregory Szorc <gregory.szorc@gmail.com>
parents:
42302
diff
changeset
|
519 role.detach_policy(PolicyArn=p.arn) |
fcb97cb91ff8
automation: detach policies before deleting role
Gregory Szorc <gregory.szorc@gmail.com>
parents:
42302
diff
changeset
|
520 |
42024
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
521 print('removing role %s' % role.name) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
522 role.delete() |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
523 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
524 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
525 def wait_for_ip_addresses(instances): |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
526 """Wait for the public IP addresses of an iterable of instances.""" |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
527 for instance in instances: |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
528 while True: |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
529 if not instance.public_ip_address: |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
530 time.sleep(2) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
531 instance.reload() |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
532 continue |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
533 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
534 print('public IP address for %s: %s' % ( |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
535 instance.id, instance.public_ip_address)) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
536 break |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
537 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
538 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
539 def remove_ami(ec2resource, image): |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
540 """Remove an AMI and its underlying snapshots.""" |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
541 snapshots = [] |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
542 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
543 for device in image.block_device_mappings: |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
544 if 'Ebs' in device: |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
545 snapshots.append(ec2resource.Snapshot(device['Ebs']['SnapshotId'])) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
546 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
547 print('deregistering %s' % image.id) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
548 image.deregister() |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
549 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
550 for snapshot in snapshots: |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
551 print('deleting snapshot %s' % snapshot.id) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
552 snapshot.delete() |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
553 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
554 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
555 def wait_for_ssm(ssmclient, instances): |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
556 """Wait for SSM to come online for an iterable of instance IDs.""" |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
557 while True: |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
558 res = ssmclient.describe_instance_information( |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
559 Filters=[ |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
560 { |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
561 'Key': 'InstanceIds', |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
562 'Values': [i.id for i in instances], |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
563 }, |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
564 ], |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
565 ) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
566 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
567 available = len(res['InstanceInformationList']) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
568 wanted = len(instances) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
569 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
570 print('%d/%d instances available in SSM' % (available, wanted)) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
571 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
572 if available == wanted: |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
573 return |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
574 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
575 time.sleep(2) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
576 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
577 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
578 def run_ssm_command(ssmclient, instances, document_name, parameters): |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
579 """Run a PowerShell script on an EC2 instance.""" |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
580 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
581 res = ssmclient.send_command( |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
582 InstanceIds=[i.id for i in instances], |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
583 DocumentName=document_name, |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
584 Parameters=parameters, |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
585 CloudWatchOutputConfig={ |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
586 'CloudWatchOutputEnabled': True, |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
587 }, |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
588 ) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
589 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
590 command_id = res['Command']['CommandId'] |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
591 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
592 for instance in instances: |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
593 while True: |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
594 try: |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
595 res = ssmclient.get_command_invocation( |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
596 CommandId=command_id, |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
597 InstanceId=instance.id, |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
598 ) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
599 except botocore.exceptions.ClientError as e: |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
600 if e.response['Error']['Code'] == 'InvocationDoesNotExist': |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
601 print('could not find SSM command invocation; waiting') |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
602 time.sleep(1) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
603 continue |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
604 else: |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
605 raise |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
606 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
607 if res['Status'] == 'Success': |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
608 break |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
609 elif res['Status'] in ('Pending', 'InProgress', 'Delayed'): |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
610 time.sleep(2) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
611 else: |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
612 raise Exception('command failed on %s: %s' % ( |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
613 instance.id, res['Status'])) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
614 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
615 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
616 @contextlib.contextmanager |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
617 def temporary_ec2_instances(ec2resource, config): |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
618 """Create temporary EC2 instances. |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
619 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
620 This is a proxy to ``ec2client.run_instances(**config)`` that takes care of |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
621 managing the lifecycle of the instances. |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
622 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
623 When the context manager exits, the instances are terminated. |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
624 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
625 The context manager evaluates to the list of data structures |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
626 describing each created instance. The instances may not be available |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
627 for work immediately: it is up to the caller to wait for the instance |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
628 to start responding. |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
629 """ |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
630 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
631 ids = None |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
632 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
633 try: |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
634 res = ec2resource.create_instances(**config) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
635 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
636 ids = [i.id for i in res] |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
637 print('started instances: %s' % ' '.join(ids)) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
638 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
639 yield res |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
640 finally: |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
641 if ids: |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
642 print('terminating instances: %s' % ' '.join(ids)) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
643 for instance in res: |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
644 instance.terminate() |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
645 print('terminated %d instances' % len(ids)) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
646 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
647 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
648 @contextlib.contextmanager |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
649 def create_temp_windows_ec2_instances(c: AWSConnection, config): |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
650 """Create temporary Windows EC2 instances. |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
651 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
652 This is a higher-level wrapper around ``create_temp_ec2_instances()`` that |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
653 configures the Windows instance for Windows Remote Management. The emitted |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
654 instances will have a ``winrm_client`` attribute containing a |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
655 ``pypsrp.client.Client`` instance bound to the instance. |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
656 """ |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
657 if 'IamInstanceProfile' in config: |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
658 raise ValueError('IamInstanceProfile cannot be provided in config') |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
659 if 'UserData' in config: |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
660 raise ValueError('UserData cannot be provided in config') |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
661 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
662 password = c.automation.default_password() |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
663 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
664 config = copy.deepcopy(config) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
665 config['IamInstanceProfile'] = { |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
666 'Name': 'hg-ephemeral-ec2-1', |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
667 } |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
668 config.setdefault('TagSpecifications', []).append({ |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
669 'ResourceType': 'instance', |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
670 'Tags': [{'Key': 'Name', 'Value': 'hg-temp-windows'}], |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
671 }) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
672 config['UserData'] = WINDOWS_USER_DATA % password |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
673 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
674 with temporary_ec2_instances(c.ec2resource, config) as instances: |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
675 wait_for_ip_addresses(instances) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
676 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
677 print('waiting for Windows Remote Management service...') |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
678 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
679 for instance in instances: |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
680 client = wait_for_winrm(instance.public_ip_address, 'Administrator', password) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
681 print('established WinRM connection to %s' % instance.id) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
682 instance.winrm_client = client |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
683 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
684 yield instances |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
685 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
686 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
687 def ensure_windows_dev_ami(c: AWSConnection, prefix='hg-'): |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
688 """Ensure Windows Development AMI is available and up-to-date. |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
689 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
690 If necessary, a modern AMI will be built by starting a temporary EC2 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
691 instance and bootstrapping it. |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
692 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
693 Obsolete AMIs will be deleted so there is only a single AMI having the |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
694 desired name. |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
695 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
696 Returns an ``ec2.Image`` of either an existing AMI or a newly-built |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
697 one. |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
698 """ |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
699 ec2client = c.ec2client |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
700 ec2resource = c.ec2resource |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
701 ssmclient = c.session.client('ssm') |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
702 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
703 name = '%s%s' % (prefix, 'windows-dev') |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
704 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
705 config = { |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
706 'BlockDeviceMappings': [ |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
707 { |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
708 'DeviceName': '/dev/sda1', |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
709 'Ebs': { |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
710 'DeleteOnTermination': True, |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
711 'VolumeSize': 32, |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
712 'VolumeType': 'gp2', |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
713 }, |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
714 } |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
715 ], |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
716 'ImageId': find_windows_server_2019_image(ec2resource).id, |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
717 'InstanceInitiatedShutdownBehavior': 'stop', |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
718 'InstanceType': 't3.medium', |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
719 'KeyName': '%sautomation' % prefix, |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
720 'MaxCount': 1, |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
721 'MinCount': 1, |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
722 'SecurityGroupIds': [c.security_groups['windows-dev-1'].id], |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
723 } |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
724 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
725 commands = [ |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
726 # Need to start the service so sshd_config is generated. |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
727 'Start-Service sshd', |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
728 'Write-Output "modifying sshd_config"', |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
729 r'$content = Get-Content C:\ProgramData\ssh\sshd_config', |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
730 '$content = $content -replace "Match Group administrators","" -replace "AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys",""', |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
731 r'$content | Set-Content C:\ProgramData\ssh\sshd_config', |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
732 'Import-Module OpenSSHUtils', |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
733 r'Repair-SshdConfigPermission C:\ProgramData\ssh\sshd_config -Confirm:$false', |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
734 'Restart-Service sshd', |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
735 'Write-Output "installing OpenSSL client"', |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
736 'Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0', |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
737 'Set-Service -Name sshd -StartupType "Automatic"', |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
738 'Write-Output "OpenSSH server running"', |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
739 ] |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
740 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
741 with INSTALL_WINDOWS_DEPENDENCIES.open('r', encoding='utf-8') as fh: |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
742 commands.extend(l.rstrip() for l in fh) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
743 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
744 # Disable Windows Defender when bootstrapping because it just slows |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
745 # things down. |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
746 commands.insert(0, 'Set-MpPreference -DisableRealtimeMonitoring $true') |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
747 commands.append('Set-MpPreference -DisableRealtimeMonitoring $false') |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
748 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
749 # Compute a deterministic fingerprint to determine whether image needs |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
750 # to be regenerated. |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
751 fingerprint = { |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
752 'instance_config': config, |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
753 'user_data': WINDOWS_USER_DATA, |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
754 'initial_bootstrap': WINDOWS_BOOTSTRAP_POWERSHELL, |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
755 'bootstrap_commands': commands, |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
756 } |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
757 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
758 fingerprint = json.dumps(fingerprint, sort_keys=True) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
759 fingerprint = hashlib.sha256(fingerprint.encode('utf-8')).hexdigest() |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
760 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
761 # Find existing AMIs with this name and delete the ones that are invalid. |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
762 # Store a reference to a good image so it can be returned one the |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
763 # image state is reconciled. |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
764 images = ec2resource.images.filter( |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
765 Filters=[{'Name': 'name', 'Values': [name]}]) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
766 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
767 existing_image = None |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
768 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
769 for image in images: |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
770 if image.tags is None: |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
771 print('image %s for %s lacks required tags; removing' % ( |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
772 image.id, image.name)) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
773 remove_ami(ec2resource, image) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
774 else: |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
775 tags = {t['Key']: t['Value'] for t in image.tags} |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
776 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
777 if tags.get('HGIMAGEFINGERPRINT') == fingerprint: |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
778 existing_image = image |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
779 else: |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
780 print('image %s for %s has wrong fingerprint; removing' % ( |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
781 image.id, image.name)) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
782 remove_ami(ec2resource, image) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
783 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
784 if existing_image: |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
785 return existing_image |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
786 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
787 print('no suitable Windows development image found; creating one...') |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
788 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
789 with create_temp_windows_ec2_instances(c, config) as instances: |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
790 assert len(instances) == 1 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
791 instance = instances[0] |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
792 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
793 wait_for_ssm(ssmclient, [instance]) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
794 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
795 # On first boot, install various Windows updates. |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
796 # We would ideally use PowerShell Remoting for this. However, there are |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
797 # trust issues that make it difficult to invoke Windows Update |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
798 # remotely. So we use SSM, which has a mechanism for running Windows |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
799 # Update. |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
800 print('installing Windows features...') |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
801 run_ssm_command( |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
802 ssmclient, |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
803 [instance], |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
804 'AWS-RunPowerShellScript', |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
805 { |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
806 'commands': WINDOWS_BOOTSTRAP_POWERSHELL.split('\n'), |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
807 }, |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
808 ) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
809 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
810 # Reboot so all updates are fully applied. |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
811 print('rebooting instance %s' % instance.id) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
812 ec2client.reboot_instances(InstanceIds=[instance.id]) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
813 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
814 time.sleep(15) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
815 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
816 print('waiting for Windows Remote Management to come back...') |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
817 client = wait_for_winrm(instance.public_ip_address, 'Administrator', |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
818 c.automation.default_password()) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
819 print('established WinRM connection to %s' % instance.id) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
820 instance.winrm_client = client |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
821 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
822 print('bootstrapping instance...') |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
823 run_powershell(instance.winrm_client, '\n'.join(commands)) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
824 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
825 print('bootstrap completed; stopping %s to create image' % instance.id) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
826 instance.stop() |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
827 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
828 ec2client.get_waiter('instance_stopped').wait( |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
829 InstanceIds=[instance.id], |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
830 WaiterConfig={ |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
831 'Delay': 5, |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
832 }) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
833 print('%s is stopped' % instance.id) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
834 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
835 image = instance.create_image( |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
836 Name=name, |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
837 Description='Mercurial Windows development environment', |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
838 ) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
839 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
840 image.create_tags(Tags=[ |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
841 { |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
842 'Key': 'HGIMAGEFINGERPRINT', |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
843 'Value': fingerprint, |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
844 }, |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
845 ]) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
846 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
847 print('waiting for image %s' % image.id) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
848 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
849 ec2client.get_waiter('image_available').wait( |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
850 ImageIds=[image.id], |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
851 ) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
852 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
853 print('image %s available as %s' % (image.id, image.name)) |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
854 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
855 return image |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
856 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
857 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
858 @contextlib.contextmanager |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
859 def temporary_windows_dev_instances(c: AWSConnection, image, instance_type, |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
860 prefix='hg-', disable_antivirus=False): |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
861 """Create a temporary Windows development EC2 instance. |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
862 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
863 Context manager resolves to the list of ``EC2.Instance`` that were created. |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
864 """ |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
865 config = { |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
866 'BlockDeviceMappings': [ |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
867 { |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
868 'DeviceName': '/dev/sda1', |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
869 'Ebs': { |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
870 'DeleteOnTermination': True, |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
871 'VolumeSize': 32, |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
872 'VolumeType': 'gp2', |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
873 }, |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
874 } |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
875 ], |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
876 'ImageId': image.id, |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
877 'InstanceInitiatedShutdownBehavior': 'stop', |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
878 'InstanceType': instance_type, |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
879 'KeyName': '%sautomation' % prefix, |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
880 'MaxCount': 1, |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
881 'MinCount': 1, |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
882 'SecurityGroupIds': [c.security_groups['windows-dev-1'].id], |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
883 } |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
884 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
885 with create_temp_windows_ec2_instances(c, config) as instances: |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
886 if disable_antivirus: |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
887 for instance in instances: |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
888 run_powershell( |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
889 instance.winrm_client, |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
890 'Set-MpPreference -DisableRealtimeMonitoring $true') |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
891 |
b05a3e28cf24
automation: perform tasks on remote machines
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
892 yield instances |