forked from bash-my-aws/bash-my-aws
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathssm-functions
452 lines (394 loc) · 16.4 KB
/
ssm-functions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
#!/usr/bin/env bash
# ssm-functions - AWS Systems Manager functions
ssm-instances() {
# List Instances known to SSM
#
# USAGE: ssm-instances [filter]
#
# $ ssm-instances
# i-00a123b456d789012 Online Amazon Linux 2 192.168.1.10 server001.example.com
# i-01b234c567e890123 Online Microsoft Windows Server 2019 Datacenter 10.0.17763 192.168.1.20 winserver002.example.com
# i-02c345d678f901234 Online Ubuntu 20.04 192.168.1.30 ubuntu003.example.com
# i-03d456e789a012345 Online Ubuntu 20.04 192.168.1.40 ubuntu004.example.com
# i-04e567f89b1234567 Online Amazon Linux 2 192.168.1.50 server005.example.com
# *Optionally provide a filter string for a `| grep` effect with tighter columisation:*
#
# $ ssm-instances Windows
# i-00a123b456d789012 Online Microsoft Windows Server 2019 Datacenter 68.0.11111 192.168.1.10 server001.example.com
# i-01b234c567e890123 Online Microsoft Windows Server 2022 Datacenter 68.0.11112 192.168.1.20 winserver002.example.com
local instances=$(skim-stdin)
local filters=$(__bma_read_filters $@)
local arg_filters="${instances:+--filters Key=InstanceIds,Values="${instances// /,}"}"
aws ssm describe-instance-information \
--output text \
$arg_filters \
--query "
InstanceInformationList[][
InstanceId,
PingStatus,
PlatformName,
PlatformVersion,
IPAddress,
ComputerName,
PlatformType
]" |
grep -E -- "$filters" |
LC_ALL=C sort -t $'\t' -k 6 |
columnise
}
ssm-send-command() {
# Run a command locally on EC2 instance(s) running Linux
#
# USAGE: ssm-send-command COMMAND instance-id [instance-id]
#
# $ ssm-send-command 'date +%F' i-0fict1234abcd
# Command ID: 12345abc-de67-f890-gh12-34ij56kl789m
# Waiting for command to complete...
# i-0fict1234abcd 2023-12-01
#
# $ ssm-instances | grep Linux | ssm-send-command 'date +%F'
# Command ID: 98b7c6d2-e3f4-11ac-8d20-47a56db09c8f
# Waiting for command to complete...
# i-0fake1234a567bcd 2023-12-01
# i-0fake2345b678cde 2023-12-01
# i-0fake3456c789def 2023-11-30
# i-0fake4567d890efa 2023-11-30
# i-0fake5678e901fgh 2023-12-01
# i-0fake6789f012ghi 2023-12-01
#
# See also: ssm-send-command-windows
local command=$1
shift
local instances=$(skim-stdin "$@")
if [[ -z $command ]] || [[ -z $instances ]]; then
echo "Usage: $0 command instance-id [instance-id]" >&2
return 1
fi
local ssm_target_platform="${ssm_target_platform:-Linux}"
local document_name
if [[ $ssm_target_platform = Linux ]]; then
document_name='AWS-RunShellScript'
elif [[ $ssm_target_platform = Windows ]]; then
document_name='AWS-RunPowerShellScript'
else
echo >&2 "Invalid value (\$ssm_target_platform ${ssm_target_platform})"
return 1
fi
if [[ $ssm_target_platform = Linux ]]; then
# If the command is a file
if [[ -f $command ]]; then
# Load contents of the file into variable
command=$(<"$command")
fi
# Base64 encode the command if it's a script
if [[ $command == *$'\n'* ]]; then
command=$(echo "$command" | base64)
command="echo $command | base64 --decode | bash"
fi
fi
# Escape double quotes in command
local escaped_command=$(echo $command | sed 's/"/\\"/g')
# Send command
local command_id
if ! command_id=$(aws ssm send-command \
--targets "Key=instanceids,Values=${instances// /,}" \
--document-name "${document_name}" \
--parameters "{\"commands\":[\"$escaped_command\"]}" \
--query "Command.CommandId" \
--output text); then
return 1
fi
echo "Command ID: $command_id" >&2
echo >&2 "Waiting for command to complete..."
for instance in $instances; do
# Wait for command to complete
aws ssm wait command-executed \
--command-id "$command_id" \
--instance-id "$instance"
# Fetch command result
aws ssm list-command-invocations \
--command-id "$command_id" \
--instance-id "$instance" \
--details \
--query "CommandInvocations[0].CommandPlugins[0].['${instance}', Output]" \
--output text
done |
columnise
}
ssm-send-command-windows() {
# Run a command locally on EC2 instance(s) running Windows
#
# USAGE: ssm-send-command-windows COMMAND instance-id [instance-id]
#
# $ ssm-send-command 'Get-Hotfix' i-0fict1234abcd
# Command ID: 12345abc-de67-f890-gh12-34ij56kl789m
# Waiting for command to complete...
# i-0fict1234abcd 2023-12-01
#
# $ ssm-instances Windows | ssm-send-command-windows Get-Hotfix
# Command ID: a0eeeddc-2edf-42bc-b0c7-122f5bc50956
# Waiting for command to complete...
# i-0fake1234abcd
# Source Description HotFixID InstalledBy InstalledOn
# ------ ----------- -------- ----------- -----------
# FAKEAPP01234 Update KB1234567 NT AUTHORITY\SYSTEM 10/11/2023 12:00:00 AM
# FAKEAPP01234 Update KB8901234 NT AUTHORITY\SYSTEM 12/12/2018 12:00:00 AM
# FAKEAPP01234 Security Update KB5678901 NT AUTHORITY\SYSTEM 12/12/2018 12:00:00 AM
# FAKEAPP01234 Update KB2345678 NT AUTHORITY\SYSTEM 1/9/2019 12:00:00 AM
# FAKEAPP01234 Update KB3456789 NT AUTHORITY\SYSTEM 3/11/2021 12:00:00 AM
# FAKEAPP01234 Security Update KB4567890 NT AUTHORITY\SYSTEM 4/21/2019 12:00:00 AM
# FAKEAPP01234 Security Update KB5678901 NT AUTHORITY\SYSTEM 5/15/2019 12:00:00 AM
# FAKEAPP01234 Security Update KB6789012 NT AUTHORITY\SYSTEM 6/12/2019 12:00:00 AM
# ---Output truncated---
# i-0fake1234abcd
# Source Description HotFixID InstalledBy InstalledOn
# ------ ----------- -------- ----------- -----------
# FAKEAPP01234 Update KB1234567 NT AUTHORITY\SYSTEM 10/11/2023 12:00:00 AM
# FAKEAPP01234 Update KB8901234 NT AUTHORITY\SYSTEM 12/12/2018 12:00:00 AM
# FAKEAPP01234 Security Update KB5678901 NT AUTHORITY\SYSTEM 12/12/2018 12:00:00 AM
#
# See also: ssm-send-command-windows
local ssm_target_platform='Windows'
ssm-send-command "$@"
}
ssm-automation-executions() {
# List recent SSM Automation Executions
# USAGE: ssm-automation-executions [filter]
#
# $ ssm-automation-executions
# 1234abcd-ef56-7890-gh12-ijk3456lmnop UpdateAndSecureNodes None Failed 2023-07-20T09:00:00.000000+00:00 None
# 5678efgh-ijkl-9012-mnop-qrstuvwx3456 UpdateAndSecureNodes i-0a1b2c3d4e5f67890 Failed 2023-07-20T09:00:10.000000+00:00 None
# 90abijkl-mnop-4567-qrst-uvwxyza12345 UpdateAndSecureNodes i-1b2c3d4e5f6g78901 Failed 2023-07-20T09:00:20.000000+00:00 None
# cdefmnop-qrst-8910-uvwx-yzab1234cdef UpdateAndSecureNodes i-2c3d4e5f6g7h89012 Failed 2023-07-20T09:00:30.000000+00:00 None
# ghijqrst-uvwx-2345-yzab-abcd5678efgh UpdateAndSecureNodes i-3d4e5f6g7h8i90123 Failed 2023-07-20T09:00:40.000000+00:00 None
local filters=$(__bma_read_filters $@)
aws ssm describe-automation-executions \
--filter Key=StartTimeAfter,Values="$(date -d yesterday -I)T00:00:00Z" \
--output text \
--query '
AutomationExecutionMetadataList[].[
AutomationExecutionId,
DocumentName,
Target,
AutomationExecutionStatus,
ExecutionStartTime,
ExecutionEndime
]' \
| grep -E -- "$filters" \
| LC_ALL=C sort -k 6 -t $'\t' \
| columnise
}
ssm-automation-execution-failures() {
local search="${@:-}"
ssm-automation-executions Failed | grep 'i-' | grep "${search}" | xargs -I{} sh -c ' echo "{}" | cut -f 1,2,3,4 | tr "\n" "\t" | tee /dev/tty | bma ssm-automation-step-executions | rg --word-regexp Failed | cut -f 2,3,4,6,8'
}
ssm-automation-step-executions() {
# Show step-by-step details for an SSM Automation Execution
#
# USAGE: automation-execution-steps execution_id [execution_id]
#
# $ ssm-automation-executions | ssm-automation-steps-executions
# [Outputs detailed step information for each provided execution ID]
local automation_executions="$(skim-stdin "$@")"
local automation_execution
for automation_execution in $automation_executions; do
# echo "Details for Automation Execution ID: $automation_execution"
aws ssm describe-automation-step-executions \
--automation-execution-id "$automation_execution" \
--output text \
--query "
StepExecutions[].[
'$automation_execution',
StepName,
StepStatus,
Action,
StepExecutionId,
ExecutionStartTime,
ExecutionEndTime,
FailureMessage
]"
echo "" # Adds a line break for readability
done \
| LC_ALL=C sort -k 5 -t $'\t' \
| columnise
}
ssm-automation-execution() {
# Show details for an SSM Automation Execution
#
# USAGE: ssm-automation-execution execution_id [execution_id]
#
# $ ssm-automation-executions | head | ssm-automation-execution
# 1234abcd-5678-9def-ghij-klmnopqrstuv DeployNewFeatures i-01234a5b6c7d8e9f0 Failed 2023-09-10T10:10:10.000000+00:00 2023-09-10T10:10:20.000000+00:00
# 9876fedc-ba98-7654-c321-onmlkjihgfed DeployNewFeatures i-09876b5c4d3e2f1g0 Failed 2023-09-10T10:20:30.000000+00:00 2023-09-10T10:20:40.000000+00:00
# abcd1234-efgh-5678-ijkl-9mnopq7rstuv DeployNewFeatures i-0a1b2c3d4e5f6g7h8 Failed 2023-09-10T10:30:50.000000+00:00 2023-09-10T10:31:00.000000+00:00
# ijkl8765-ghij-4321-klmn-5opq4rstu3vw DeployNewFeatures i-0i8j7k6l5m4n3o2p1 Failed 2023-09-10T10:40:10.000000+00:00 2023-09-10T10:40:20.000000+00:00
local automation_executions="$(skim-stdin "$@")"
local automation_execution
for automation_execution in $automation_executions; do
aws ssm get-automation-execution \
--automation-execution-id "$automation_execution" \
--output text \
--query "
AutomationExecution.[
AutomationExecutionId,
DocumentName,
Parameters.InstanceId,
Parameters.InstallDefender,
AutomationExecutionStatus,
ExecutionStartTime,
ExecutionEndTime
][]"
done \
| LC_ALL=C sort -k 6 -t $'\t' \
| columnise
}
ssm-associations() {
# List SSM associations
#
# USAGE: ssm-associations [filter]
#
# $ ssm-associations
# Task-RunSecurityScan cron(30 2 * * SUN) 2023-01-15T02:30:00.000000+00:00 Failed
# Task-UpdateSystemPackages cron(0 4 * * SAT) 2023-04-22T04:00:00.000000+00:00 Success
# Service-ConfigureNetworkSettings rate(7 days) 2023-05-07T11:00:00.000000+00:00 Success
# Script-DeployMonitoringTools cron(15 3 * * FRI) 2023-03-03T03:15:00.000000+00:00 Failed
local filters=$(__bma_read_filters $@)
aws ssm list-associations \
--query 'Associations[].[
AssociationId,
AssociationName,
Name,
ScheduleExpression,
LastExecutionDate,
Overview.Status]' \
--output text |
grep -E -- "$filters" |
columnise
}
ssm-association-executions() {
# List SSM Association Executions
#
# USAGE: ssm-associations [filter]
#
# $ ssm-associations
# 12345678-9abc-def0-1234-56789abcdef0 a1b2c3d4-e5f6-7890-a1b2-c3d4e5f67890 Success {Success=10} 2023-07-21T10:30:00.000000+00:00
# 12345678-9abc-def0-1234-56789abcdef0 b1c2d3e4-f5g6-7890-b1c2-d3e4f5g67890 Success {Success=15} 2023-07-22T11:00:00.000000+00:00
# 12345678-9abc-def0-1234-56789abcdef0 c1d2e3f4-g5h6-7890-c1d2-e3f4g5h67890 Success {Success=13} 2023-07-23T09:45:00.000000+00:00
# 12345678-9abc-def0-1234-56789abcdef0 d1e2f3g4-h5i6-7890-d1e2-f3g4h5i67890 Failed {Failed=2, Success=12} 2023-07-24T12:30:00.000000+00:00
# 12345678-9abc-def0-1234-56789abcdef0 e1f2g3h4-i5j6-7890-e1f2-g3h4i5j67890 Failed {Failed=3, Success=11} 2023-07-25T14:15:00.000000+00:00
local associations=$(skim-stdin "$@")
[[ -z $associations ]] && __bma_usage "association [association]" && return 1
local association
for association in $associations; do
aws ssm describe-association-executions \
--association-id "$association" \
--output text \
--query '
AssociationExecutions[].[
AssociationId,
ExecutionId,
Status,
ResourceCountByStatus,
CreatedTime
]' \
| LC_ALL=C sort -k 5 -t $'\t' \
| columnise
done
}
ssm-association-execution-targets() {
# List targets for SSM Association Execution
#
# USAGE: ssm-association-execution-targets association-id execution-id
#
# $ association-execution-targets abcd1234-ef56-7890-gh12-ijk3456lmnop 12345678-90ab-cdef-1234-567890abcdef
# abcd1234-ef56-7890-gh12-ijk3456lmnop 12345678-90ab-cdef-1234-567890abcdef i-01234abcde56789f0 Success Success 2023-08-10T11:30:00.000000+00:00
# abcd1234-ef56-7890-gh12-ijk3456lmnop 12345678-90ab-cdef-1234-567890abcdef i-02345bcdef67891g1 Success Success 2023-08-10T11:30:10.000000+00:00
# abcd1234-ef56-7890-gh12-ijk3456lmnop 12345678-90ab-cdef-1234-567890abcdef i-03456cdefg78912h2 Success Success 2023-08-10T11:30:20.000000+00:00
# abcd1234-ef56-7890-gh12-ijk3456lmnop 12345678-90ab-cdef-1234-567890abcdef i-04567defgh89123i3 Success Success 2023-08-10T11:30:30.000000+00:00
#
# Note: Can't use skim-stdin as it requires to arguments
local association_id="$1"
local execution_id="$2"
aws ssm describe-association-execution-targets \
--association-id "$association_id" \
--execution-id "$execution_id" \
--output text \
--query "
AssociationExecutionTargets[].[
AssociationId,
ExecutionId,
ResourceId,
Status,
DetailedStatus,
LastExecutionDate
]" \
| LC_ALL=C sort -k 5 -t $'\t' \
| columnise
}
ssm-parameters() {
# List SSM Parameters
#
# USAGE: ssm-parameters [filter]
#
# $ ssm-parameters
# /company/ad/a1234567/username
# /ami/Ubuntu-20.04-proxy
# /cloudwatch-agent/config/general
# /cnf/staticSite/B1P2V34SR5KF0Z/encryptionKeyArn
# /ops/CloudMetrics/linux
# /ops/CloudMetrics/windows
local filters=$(__bma_read_filters $@)
aws ssm describe-parameters \
--output text \
--query 'Parameters[].[Name]' \
| grep -E -- "$filters" \
| LC_ALL=C sort
}
ssm-parameter-value() {
# Print SSM Parameter Value
#
# USAGE: ssm-parameter-value ssm-parameter [ssm-parameter]
#
# $ ssm-parameters | ssm-parameter-value
# /ops/Monitoring/metrics/unix
# {
# "agent": {
# "metrics_collection_interval": 60,
# "logfile": "/var/log/aws-monitoring/aws-monitoring-agent.log"
# },
# "logs": {
# "logs_collected": {
# "files": {
# <snip>
local parameters=$(skim-stdin "$@")
local parameter
for parameter in $parameters; do
echo -e "\n${parameter}"
aws ssm get-parameter \
--name "$parameter" \
--query Parameter.Value \
--output json
done
}
instance-ssm-platform-type() {
# Show platform type (OS) for instance
#
# USAGE: instance-ssm-platform-type instance-id [instance-id]
#
# $ instances | instance-ssm-platform-type
# i-0c1d2e3f4a567890b None
# i-0d1c2b3a4e5f6789c Linux
# i-0e1f2d3c4b5a6789d Linux
# i-0f1e2d3c4b5a6789e None
# i-0a9f8e7d6c5b4a312 None
# i-01b2a3c4d5e6f7893 Windows
local instance_ids=$(skim-stdin "$@")
if [[ -z $instance_ids ]]; then
echo "Usage: $FUNCNAME instance-id [instance-id]"
return 1
fi
for instance_id in $instance_ids; do
local platform_type=$(aws --no-cli-pager ssm describe-instance-information --filters "Key=InstanceIds,Values=${instance_id}" --query 'InstanceInformationList[0].PlatformType' --output text)
echo -e "$instance_id\t$platform_type"
done
}