Skip to content

Commit e38f12b

Browse files
committed
Merge branch 'feature/PI-873-split_support_policy' into release/2025-04-02
2 parents ba8747d + 8d8550b commit e38f12b

File tree

6 files changed

+409
-24
lines changed

6 files changed

+409
-24
lines changed

scripts/infrastructure/policies/support-policy.json

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -252,30 +252,6 @@
252252
"apigateway:POST"
253253
],
254254
"Resource": ["arn:aws:apigateway:*::/*"]
255-
},
256-
{
257-
"Sid": "CertificateSupportPermissions",
258-
"Effect": "Allow",
259-
"Action": ["acm:ListTagsForCertificate", "acm:DescribeCertificate"],
260-
"Resource": ["arn:aws:acm:*:{$ACCOUNT_ID}:certificate*"]
261-
},
262-
{
263-
"Sid": "BillingSupportPermissions",
264-
"Effect": "Allow",
265-
"Action": [
266-
"ce:GetCostAndUsage",
267-
"ce:GetCostForcast",
268-
"ce:GetAnomalies",
269-
"ce:GetTags",
270-
"budgets:ViewBudget"
271-
],
272-
"Resource": [
273-
"arn:aws:ce:*:{$ACCOUNT_ID}:GetCostAndUsage",
274-
"arn:aws:ce:*:{$ACCOUNT_ID}:GetCostForecast",
275-
"arn:aws:ce:*:{$ACCOUNT_ID}:GetTags",
276-
"arn:aws:ce:*:{$ACCOUNT_ID}:anomalymonitor/*",
277-
"arn:aws:budgets::{$ACCOUNT_ID}:budget/*"
278-
]
279255
}
280256
]
281257
}
Lines changed: 257 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,257 @@
1+
{
2+
"Version": "2012-10-17",
3+
"Statement": [
4+
{
5+
"Sid": "IamSupportPermissions",
6+
"Effect": "Allow",
7+
"Action": [
8+
"iam:GetPolicyVersion",
9+
"iam:ListRoleTags",
10+
"iam:ListPolicyTags",
11+
"iam:ListRolePolicies",
12+
"iam:GetRole",
13+
"iam:GetPolicy",
14+
"iam:ListGroupPolicies",
15+
"iam:ListPolicyVersions",
16+
"iam:GetGroupPolicy",
17+
"iam:GetRolePolicy",
18+
"iam:ListPolicies",
19+
"iam:ListRoles",
20+
"iam:ListGroups",
21+
"iam:ListUsers",
22+
"iam:ListAttachedRolePolicies"
23+
],
24+
"Resource": [
25+
"arn:aws:iam::${ACCOUNT_ID}:role/*",
26+
"arn:aws:iam::${ACCOUNT_ID}:group/*",
27+
"arn:aws:iam::${ACCOUNT_ID}:policy/*"
28+
]
29+
},
30+
{
31+
"Sid": "IamSupportPermissionsAll",
32+
"Effect": "Allow",
33+
"Action": ["iam:ListAccountAliases", "iam:GetAccountSummary"],
34+
"Resource": ["*"]
35+
},
36+
{
37+
"Sid": "DynamoDbSupportPermissions",
38+
"Effect": "Allow",
39+
"Action": [
40+
"dynamodb:BatchGetItem",
41+
"dynamodb:UpdateTimeToLive",
42+
"dynamodb:ConditionCheckItem",
43+
"dynamodb:PutItem",
44+
"dynamodb:DeleteItem",
45+
"dynamodb:DescribeContributorInsights",
46+
"dynamodb:Scan",
47+
"dynamodb:ListTagsOfResource",
48+
"dynamodb:Query",
49+
"dynamodb:UpdateItem",
50+
"dynamodb:CreateBackup",
51+
"dynamodb:DescribeTimeToLive",
52+
"dynamodb:PartiQLSelect",
53+
"dynamodb:DescribeTable",
54+
"dynamodb:GetItem",
55+
"dynamodb:DescribeContinuousBackups",
56+
"dynamodb:DescribeKinesisStreamingDestination",
57+
"dynamodb:DescribeTableReplicaAutoScaling",
58+
"dynamodb:ListContributorInsights",
59+
"dynamodb:DescribeReservedCapacityOfferings",
60+
"dynamodb:ListGlobalTables",
61+
"dynamodb:ListTables",
62+
"dynamodb:DescribeReservedCapacity",
63+
"dynamodb:ListBackups",
64+
"dynamodb:ListImports",
65+
"dynamodb:DescribeLimits",
66+
"dynamodb:DescribeEndpoints",
67+
"dynamodb:ListExports",
68+
"dynamodb:ListStreams"
69+
],
70+
"Resource": [
71+
"arn:aws:dynamodb:*:${ACCOUNT_ID}:table/*",
72+
"arn:aws:dynamodb::${ACCOUNT_ID}:global-table/*"
73+
]
74+
},
75+
{
76+
"Sid": "CloudFormationSupportPermissions",
77+
"Effect": "Allow",
78+
"Action": [
79+
"cloudformation:DescribeStacks",
80+
"cloudformation:ListStackResources",
81+
"cloudformation:ListStacks"
82+
],
83+
"Resource": ["*"]
84+
},
85+
{
86+
"Sid": "TagSupportPermissions",
87+
"Effect": "Allow",
88+
"Action": [
89+
"tag:GetResources",
90+
"tag:GetTagValues",
91+
"tag:GetTagKeys",
92+
"tag:GetComplianceSummary",
93+
"tag:DescribeReportCreation"
94+
],
95+
"Resource": "*"
96+
},
97+
{
98+
"Sid": "LambdaSupportPermissions",
99+
"Effect": "Allow",
100+
"Action": [
101+
"lambda:ListAliases",
102+
"lambda:ListFunctionUrlConfigs",
103+
"lambda:ListTags",
104+
"lambda:ListVersionsByFunction",
105+
"lambda:ListLayerVersions",
106+
"lambda:GetAlias",
107+
"lambda:GetFunction",
108+
"lambda:GetLayerVersion",
109+
"lambda:GetFunctionEventInvokeConfig",
110+
"lambda:ListProvisionedConcurrencyConfigs",
111+
"lambda:GetFunctionUrlConfig"
112+
],
113+
"Resource": [
114+
"arn:aws:lambda:*:${ACCOUNT_ID}:function:*",
115+
"arn:aws:lambda:*:${ACCOUNT_ID}:layer:*:*"
116+
]
117+
},
118+
{
119+
"Sid": "LambdaSupportAllPermissions",
120+
"Effect": "Allow",
121+
"Action": [
122+
"lambda:ListFunctions",
123+
"lambda:ListLayers",
124+
"lambda:GetAccountSettings"
125+
],
126+
"Resource": ["*"]
127+
},
128+
{
129+
"Sid": "ResourceGroupSupportPermissions",
130+
"Effect": "Allow",
131+
"Action": [
132+
"resource-groups:GetAccountSettings",
133+
"resource-groups:GetGroupQuery",
134+
"resource-groups:GetTags",
135+
"resource-groups:GetGroup",
136+
"resource-groups:GetGroupConfiguration",
137+
"resource-groups:ListGroupResources",
138+
"resource-groups:SearchResources",
139+
"resource-groups:ListGroups"
140+
],
141+
"Resource": ["*"]
142+
},
143+
{
144+
"Sid": "CloudwatchSupportPermissions",
145+
"Effect": "Allow",
146+
"Action": [
147+
"cloudwatch:ListTagsForResource",
148+
"cloudwatch:ListMetrics",
149+
"cloudwatch:ListMetricStreams",
150+
"cloudwatch:DescribeAlarmHistory",
151+
"cloudwatch:DescribeAlarms",
152+
"cloudwatch:DescribeAlarmsForMetric",
153+
"cloudwatch:DescribeAnomalyDetectors",
154+
"cloudwatch:DescribeInsightRules",
155+
"cloudwatch:GetDashboard",
156+
"cloudwatch:GetInsightRuleReport",
157+
"cloudwatch:GetMetricData",
158+
"cloudwatch:GetMetricWidgetImage",
159+
"cloudwatch:GetMetricStream",
160+
"cloudwatch:GetMetricStatistics",
161+
"cloudwatch:GenerateQuery",
162+
"cloudwatch:ListManagedInsightRules",
163+
"cloudwatch:ListDashboards"
164+
],
165+
"Resource": [
166+
"arn:aws:cloudwatch:*:${ACCOUNT_ID}:alarm:*",
167+
"arn:aws:cloudwatch::${ACCOUNT_ID}:dashboard/*",
168+
"arn:aws:cloudwatch:*:${ACCOUNT_ID}:insight-rule/*",
169+
"arn:aws:cloudwatch:*:${ACCOUNT_ID}:metric-stream/*"
170+
]
171+
},
172+
{
173+
"Sid": "LogSupportPermissions",
174+
"Effect": "Allow",
175+
"Action": [
176+
"logs:ListAnomalies",
177+
"logs:GetDelivery",
178+
"logs:GetDeliverySource",
179+
"logs:GetLogEvents",
180+
"logs:GetDeliveryDestinationPolicy",
181+
"logs:GetDeliveryDestination",
182+
"logs:GetLogAnomalyDetector",
183+
"logs:ListTagsForResource",
184+
"logs:GetLogDelivery",
185+
"logs:ListLogDeliveries",
186+
"logs:StartLiveTail",
187+
"logs:StopLiveTail",
188+
"logs:DescribeQueryDefinitions",
189+
"logs:DescribeResourcePolicies",
190+
"logs:DescribeDestinations",
191+
"logs:DescribeQueries",
192+
"logs:DescribeLogGroups",
193+
"logs:DescribeAccountPolicies",
194+
"logs:DescribeDeliverySources",
195+
"logs:StopQuery",
196+
"logs:TestMetricFilter",
197+
"logs:DescribeDeliveryDestinations",
198+
"logs:DescribeExportTasks",
199+
"logs:DescribeDeliveries",
200+
"logs:GetDataProtectionPolicy",
201+
"logs:GetLogRecord",
202+
"logs:DescribeSubscriptionFilters",
203+
"logs:StartQuery",
204+
"logs:DescribeMetricFilters",
205+
"logs:FilterLogEvents",
206+
"logs:Unmask",
207+
"logs:ListTagsForResource",
208+
"logs:GetQueryResults",
209+
"logs:ListTagsLogGroup",
210+
"logs:DescribeLogStreams",
211+
"logs:ListLogAnomalyDetectors",
212+
"logs:GetLogGroupFields"
213+
],
214+
"Resource": [
215+
"arn:aws:logs:*:${ACCOUNT_ID}:anomaly-detector:*",
216+
"arn:aws:logs:*:${ACCOUNT_ID}:delivery:*",
217+
"arn:aws:logs:*:${ACCOUNT_ID}:delivery-destination:*",
218+
"arn:aws:logs:*:${ACCOUNT_ID}:delivery-source:*",
219+
"arn:aws:logs:*:${ACCOUNT_ID}:destination:*",
220+
"arn:aws:logs:*:${ACCOUNT_ID}:log-group:*",
221+
"arn:aws:logs:*:${ACCOUNT_ID}:log-group:*:log-stream:*"
222+
]
223+
},
224+
{
225+
"Sid": "KMSSupportPermissions",
226+
"Effect": "Allow",
227+
"Action": [
228+
"kms:DescribeKey",
229+
"kms:Decrypt",
230+
"kms:DisableKey",
231+
"kms:DisableKeyRotation",
232+
"kms:EnableKey",
233+
"kms:EnableKeyRotation",
234+
"kms:GetKeyPolicy",
235+
"kms:GetKeyRotationStatus",
236+
"kms:ListAliases",
237+
"kms:ListResourceTags",
238+
"kms:ScheduleKeyDeletion",
239+
"kms:UpdateAlias",
240+
"kms:UpdateKeyDescription"
241+
],
242+
"Resource": ["*"]
243+
},
244+
{
245+
"Sid": "APIGatewaySupportPermissions",
246+
"Effect": "Allow",
247+
"Action": [
248+
"apigateway:DELETE",
249+
"apigateway:GET",
250+
"apigateway:PATCH",
251+
"apigateway:PUT",
252+
"apigateway:POST"
253+
],
254+
"Resource": ["arn:aws:apigateway:*::/*"]
255+
}
256+
]
257+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"Version": "2012-10-17",
3+
"Statement": [
4+
{
5+
"Sid": "CertificateSupportPermissions",
6+
"Effect": "Allow",
7+
"Action": ["acm:ListTagsForCertificate", "acm:DescribeCertificate"],
8+
"Resource": ["*"]
9+
},
10+
{
11+
"Sid": "BudgetSupportPermissions",
12+
"Effect": "Allow",
13+
"Action": ["budgets:ViewBudget"],
14+
"Resource": ["*"]
15+
},
16+
{
17+
"Sid": "BillingSupportPermissions",
18+
"Effect": "Allow",
19+
"Action": [
20+
"ce:GetCostAndUsage",
21+
"ce:GetCostForecast",
22+
"ce:GetAnomalies",
23+
"ce:GetTags"
24+
],
25+
"Resource": ["*"]
26+
}
27+
]
28+
}

scripts/infrastructure/roles.mk

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@ manage--non-mgmt-development-policies: aws--login ## Create or update IAM Polici
1212
manage--mgmt-development-policies: aws--login ## Create or update IAM Policies
1313
@AWS_ACCESS_KEY_ID=$(AWS_ACCESS_KEY_ID) AWS_SECRET_ACCESS_KEY=$(AWS_SECRET_ACCESS_KEY) AWS_SESSION_TOKEN=$(AWS_SESSION_TOKEN) bash $(PATH_TO_INFRASTRUCTURE)/roles/manage-mgmt-aws-development-policies.sh
1414

15+
manage--non-mgmt-support-policies: aws--login ## Create or update IAM Policies
16+
@AWS_ACCESS_KEY_ID=$(AWS_ACCESS_KEY_ID) AWS_SECRET_ACCESS_KEY=$(AWS_SECRET_ACCESS_KEY) AWS_SESSION_TOKEN=$(AWS_SESSION_TOKEN) bash $(PATH_TO_INFRASTRUCTURE)/roles/manage-non-mgmt-aws-support-policies.sh
17+
18+
manage--mgmt-support-policies: aws--login ## Create or update IAM Policies
19+
@AWS_ACCESS_KEY_ID=$(AWS_ACCESS_KEY_ID) AWS_SECRET_ACCESS_KEY=$(AWS_SECRET_ACCESS_KEY) AWS_SESSION_TOKEN=$(AWS_SESSION_TOKEN) bash $(PATH_TO_INFRASTRUCTURE)/roles/manage-mgmt-aws-support-policies.sh
20+
1521
manage--non-mgmt-test-policies: aws--login ## Create or update IAM Policies
1622
@AWS_ACCESS_KEY_ID=$(AWS_ACCESS_KEY_ID) AWS_SECRET_ACCESS_KEY=$(AWS_SECRET_ACCESS_KEY) AWS_SESSION_TOKEN=$(AWS_SESSION_TOKEN) bash $(PATH_TO_INFRASTRUCTURE)/roles/manage-non-mgmt-aws-support-integration-policies.sh
1723

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#!/bin/bash
2+
3+
function _substitute_environment_variables() {
4+
eval "cat << EOF
5+
$(cat $1)
6+
EOF"
7+
}
8+
9+
AWS_REGION_NAME="eu-west-2"
10+
11+
ACCOUNT_ID=$(aws sts get-caller-identity | jq -r .Account)
12+
13+
#
14+
# Check we're running this against MGMT
15+
#
16+
. "./scripts/aws/helpers.sh"
17+
if ! _validate_current_account "MGMT"; then
18+
echo "Please login to mgmt profile before running this script"
19+
exit 1
20+
fi
21+
22+
#
23+
# Create the NHSDevelopmentPolicy that will be used for Developer access and
24+
# NHSDevelopmentRole. This policy is split into 2 as the file size was too large.
25+
#
26+
27+
policy_name="NHSSupportPolicy"
28+
29+
for policy_number in "1" "2"; do
30+
tf_policy=$(_substitute_environment_variables ./scripts/infrastructure/policies/support${policy_number}-policy.json)
31+
aws iam get-policy --policy-arn "arn:aws:iam::${ACCOUNT_ID}:policy/${policy_name}${policy_number}" &>/dev/null
32+
if [ $? != 0 ]; then
33+
aws iam create-policy \
34+
--policy-name "${policy_name}${policy_number}" \
35+
--policy-document "${tf_policy}" \
36+
--region "${AWS_REGION_NAME}" ||
37+
exit 1
38+
fi
39+
# We update the version because this updates all roles and we don't have to detach and delete.
40+
versions=$(aws iam list-policy-versions --policy-arn "arn:aws:iam::${ACCOUNT_ID}:policy/${policy_name}${policy_number}" --region "${AWS_REGION_NAME}")
41+
num_versions=$(echo "$versions" | jq -r '.Versions | length')
42+
# There has got to be at least 2 versions.
43+
if [ "$num_versions" -ge 2 ]; then
44+
# Extract the oldest version using jq
45+
oldest_version=$(echo "$versions" | jq -r '.Versions | sort_by(.CreateDate) | .[0].VersionId')
46+
47+
aws iam delete-policy-version \
48+
--policy-arn "arn:aws:iam::${ACCOUNT_ID}:policy/${policy_name}${policy_number}" \
49+
--version-id "${oldest_version}" ||
50+
exit 1
51+
fi
52+
53+
aws iam create-policy-version \
54+
--policy-arn "arn:aws:iam::${ACCOUNT_ID}:policy/${policy_name}${policy_number}" \
55+
--policy-document "${tf_policy}" \
56+
--set-as-default \
57+
--region "${AWS_REGION_NAME}" ||
58+
exit 1
59+
done

0 commit comments

Comments
 (0)