Skip to content

Commit 24050f2

Browse files
preprod db seeding
1 parent d308c2d commit 24050f2

20 files changed

Lines changed: 664 additions & 24 deletions
File renamed without changes.
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
name: Preprod - Seed DynamoDB table
2+
3+
on:
4+
push:
5+
branches:
6+
- ELI-417-preprod-db-seeding
7+
8+
jobs:
9+
seed:
10+
runs-on: ubuntu-latest
11+
environment: "dev"
12+
permissions:
13+
id-token: write
14+
contents: read
15+
env:
16+
AWS_REGION: eu-west-2
17+
DATA_FOLDER: vitaIntegrationTestData/
18+
DYNAMODB_TABLE: eligibility-signposting-api-dev-eligibility_datastore
19+
20+
steps:
21+
- name: Checkout repo
22+
uses: actions/checkout@v5
23+
24+
- name: Set up Python
25+
uses: actions/setup-python@v5
26+
with:
27+
python-version: '3.13'
28+
29+
- name: Install dependencies
30+
run: pip install boto3
31+
32+
- name: "Configure AWS Credentials"
33+
uses: aws-actions/configure-aws-credentials@v4
34+
with:
35+
role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/service-roles/github-actions-api-deployment-role
36+
aws-region: ${{ env.AWS_REGION }}
37+
38+
- name: Run seed script
39+
run: |
40+
python .github/scripts/seed_dynamodb.py \
41+
--table-name "${{ env.DYNAMODB_TABLE }}" \
42+
--region "${{ env.AWS_REGION }}" \
43+
--data-folder "${{ env.DATA_FOLDER }}"

infrastructure/stacks/iams-developer-roles/github_actions_policies.tf

Lines changed: 40 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -89,24 +89,40 @@ resource "aws_iam_policy" "dynamodb_management" {
8989

9090
policy = jsonencode({
9191
Version = "2012-10-17",
92-
Statement = [
93-
{
94-
Effect = "Allow",
95-
Action = [
96-
"dynamodb:DescribeTimeToLive",
97-
"dynamodb:DescribeTable",
98-
"dynamodb:DescribeContinuousBackups",
99-
"dynamodb:ListTables",
100-
"dynamodb:DeleteTable",
101-
"dynamodb:CreateTable",
102-
"dynamodb:TagResource",
103-
"dynamodb:ListTagsOfResource",
104-
],
105-
Resource = [
106-
"arn:aws:dynamodb:*:${data.aws_caller_identity.current.account_id}:table/*eligibility-signposting-api-${var.environment}-eligibility_datastore"
107-
]
108-
}
109-
]
92+
Statement = concat(
93+
[
94+
{
95+
Effect = "Allow",
96+
Action = [
97+
"dynamodb:DescribeTimeToLive",
98+
"dynamodb:DescribeTable",
99+
"dynamodb:DescribeContinuousBackups",
100+
"dynamodb:ListTables",
101+
"dynamodb:DeleteTable",
102+
"dynamodb:CreateTable",
103+
"dynamodb:TagResource",
104+
"dynamodb:ListTagsOfResource",
105+
],
106+
Resource = [
107+
"arn:aws:dynamodb:*:${data.aws_caller_identity.current.account_id}:table/*eligibility-signposting-api-${var.environment}-eligibility_datastore"
108+
]
109+
}
110+
],
111+
# to create test users in preprod
112+
var.environment == "preprod" ? [
113+
{
114+
Effect = "Allow",
115+
Action = [
116+
"dynamodb:GetItem",
117+
"dynamodb:PutItem",
118+
"dynamodb:DeleteItem",
119+
],
120+
Resource = [
121+
"arn:aws:dynamodb:*:${data.aws_caller_identity.current.account_id}:table/*eligibility-signposting-api-preprod-eligibility_datastore"
122+
]
123+
}
124+
] : []
125+
)
110126
})
111127

112128
tags = merge(local.tags, { Name = "dynamodb-management" })
@@ -465,8 +481,8 @@ resource "aws_iam_policy" "iam_management" {
465481
# Assume role policy document for GitHub Actions
466482
data "aws_iam_policy_document" "github_actions_assume_role" {
467483
statement {
468-
sid = "OidcAssumeRoleWithWebIdentity"
469-
effect = "Allow"
484+
sid = "OidcAssumeRoleWithWebIdentity"
485+
effect = "Allow"
470486
actions = ["sts:AssumeRoleWithWebIdentity"]
471487

472488
principals {
@@ -479,13 +495,13 @@ data "aws_iam_policy_document" "github_actions_assume_role" {
479495
condition {
480496
test = "StringLike"
481497
variable = "token.actions.githubusercontent.com:sub"
482-
values = ["repo:${var.github_org}/${var.github_repo}:*"]
498+
values = ["repo:${var.github_org}/${var.github_repo}:*"]
483499
}
484500

485501
condition {
486502
test = "StringEquals"
487503
variable = "token.actions.githubusercontent.com:aud"
488-
values = ["sts.amazonaws.com"]
504+
values = ["sts.amazonaws.com"]
489505
}
490506
}
491507
}
@@ -514,8 +530,8 @@ resource "aws_iam_policy" "firehose_readonly" {
514530
"firehose:StopDeliveryStreamEncryption"
515531
]
516532
Resource = [
517-
"arn:aws:firehose:${var.default_aws_region}:${data.aws_caller_identity.current.account_id}:deliverystream/eligibility-signposting-api*",
518-
"arn:aws:firehose:${var.default_aws_region}:${data.aws_caller_identity.current.account_id}:deliverystream/splunk-alarm-events*"
533+
"arn:aws:firehose:${var.default_aws_region}:${data.aws_caller_identity.current.account_id}:deliverystream/eligibility-signposting-api*",
534+
"arn:aws:firehose:${var.default_aws_region}:${data.aws_caller_identity.current.account_id}:deliverystream/splunk-alarm-events*"
519535
]
520536
}
521537
]

infrastructure/stacks/iams-developer-roles/iams_permissions_boundary.tf

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ data "aws_iam_policy_document" "permissions_boundary" {
3636
"dynamodb:CreateTable",
3737
"dynamodb:TagResource",
3838
"dynamodb:ListTagsOfResource",
39+
# Only used in preprod
40+
"dynamodb:GetItem",
41+
"dynamodb:PutItem",
42+
"dynamodb:DeleteItem",
3943

4044
# EC2 - networking infrastructure
4145
"ec2:Describe*",

scripts/seed_users/__init__.py

Whitespace-only changes.
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import argparse
2+
import glob
3+
import json
4+
import os
5+
6+
import boto3
7+
8+
9+
def parse_args():
10+
parser = argparse.ArgumentParser(description="Seed DynamoDB table with JSON data.")
11+
parser.add_argument("--table-name", required=True, help="Name of the DynamoDB table")
12+
parser.add_argument("--region", default="eu-west-2", help="AWS region")
13+
parser.add_argument("--data-folder", default="vitaIntegrationTestData/", help="Folder containing JSON seed data")
14+
return parser.parse_args()
15+
16+
17+
def clear_table(table):
18+
scan = table.scan(
19+
ProjectionExpression="#nhs, #type", ExpressionAttributeNames={"#nhs": "NHS_NUMBER", "#type": "ATTRIBUTE_TYPE"}
20+
)
21+
with table.batch_writer() as batch:
22+
for item in scan["Items"]:
23+
batch.delete_item(Key={"NHS_NUMBER": item["NHS_NUMBER"], "ATTRIBUTE_TYPE": item["ATTRIBUTE_TYPE"]})
24+
25+
26+
def insert_data_from_folder(table, data_folder):
27+
json_files = glob.glob(os.path.join(data_folder, "*.json"))
28+
for file_path in json_files:
29+
with open(file_path) as f:
30+
try:
31+
payload = json.load(f)
32+
items = payload.get("data", [])
33+
except Exception as e:
34+
print(f"Skipping {file_path}: {e}")
35+
continue
36+
37+
with table.batch_writer() as batch:
38+
for item in items:
39+
nhs_number = item.get("NHS_NUMBER")
40+
attr_type = item.get("ATTRIBUTE_TYPE")
41+
if nhs_number and attr_type:
42+
item["id"] = nhs_number
43+
batch.put_item(Item=item)
44+
45+
46+
def main():
47+
args = parse_args()
48+
dynamodb = boto3.resource("dynamodb", region_name=args.region)
49+
table = dynamodb.Table(args.table_name)
50+
51+
clear_table(table)
52+
insert_data_from_folder(table, args.data_folder)
53+
54+
55+
if __name__ == "__main__":
56+
main()
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
{
2+
"scenario_name": "RSV - Vita Integration - Actionable - You should have the RSV vaccine ( in CP area ) - age rolling - BookNBS",
3+
"request_headers": {
4+
"nhs-login-nhs-number": "9686368973"
5+
},
6+
"config_filenames": [
7+
"vita_integration_test_config.json"
8+
],
9+
"data": [
10+
{
11+
"NHS_NUMBER": "9686368973",
12+
"ATTRIBUTE_TYPE": "COHORTS",
13+
"COHORT_MEMBERSHIPS": [
14+
{
15+
"COHORT_LABEL": "rsv_75to79",
16+
"DATE_JOINED": "20231020"
17+
}
18+
]
19+
},
20+
{
21+
"NHS_NUMBER": "9686368973",
22+
"ATTRIBUTE_TYPE": "PERSON",
23+
"DATE_OF_BIRTH": "<<DATE_AGE_75>>",
24+
"GENDER": "0",
25+
"POSTCODE": "SG8 6EG",
26+
"POSTCODE_SECTOR": "SG86",
27+
"POSTCODE_OUTCODE": "SG8",
28+
"MSOA": "E02003792",
29+
"LSOA": "E01018267",
30+
"LOCAL_AUTHORITY": "E08000011",
31+
"GP_PRACTICE_CODE": "D81046",
32+
"PCN": "U75549",
33+
"ICB": "QUE",
34+
"COMMISSIONING_REGION": "Y61",
35+
"13Q_FLAG": "N",
36+
"CARE_HOME_FLAG": "N",
37+
"DE_FLAG": "N"
38+
}
39+
]
40+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
{
2+
"scenario_name": "RSV - Vita Integration - Actionable - You should have the RSV vaccine ( out CP area ) - age rolling - age rolling - BookLocal",
3+
"request_headers": {
4+
"nhs-login-nhs-number": "9686368906"
5+
},
6+
"config_filenames": [
7+
"vita_integration_test_config.json"
8+
],
9+
"data": [
10+
{
11+
"NHS_NUMBER": "9686368906",
12+
"ATTRIBUTE_TYPE": "COHORTS",
13+
"COHORT_MEMBERSHIPS": [
14+
{
15+
"COHORT_LABEL": "rsv_75to79",
16+
"DATE_JOINED": "20231020"
17+
}
18+
]
19+
},
20+
{
21+
"NHS_NUMBER": "9686368906",
22+
"ATTRIBUTE_TYPE": "PERSON",
23+
"DATE_OF_BIRTH": "19500601",
24+
"GENDER": "2",
25+
"POSTCODE": "CB3 8DX",
26+
"POSTCODE_SECTOR": "CB38",
27+
"POSTCODE_OUTCODE": "CB3",
28+
"MSOA": "E02007085",
29+
"LSOA": "E01018223",
30+
"GP_PRACTICE_CODE": "D81046",
31+
"PCN": "U75549",
32+
"ICB": "QUE",
33+
"COMMISSIONING_REGION": "Y61",
34+
"13Q_FLAG": "N",
35+
"CARE_HOME_FLAG": "N",
36+
"DE_FLAG": "N"
37+
}
38+
]
39+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
{
2+
"scenario_name": "RSV - Vita Integration - Actionable - You should have the RSV vaccine ( out CP area ) - age catchup - BookLocal",
3+
"request_headers": {
4+
"nhs-login-nhs-number": "9658218873"
5+
},
6+
"config_filenames": [
7+
"vita_integration_test_config.json"
8+
],
9+
"data": [
10+
{
11+
"NHS_NUMBER": "9658218873",
12+
"ATTRIBUTE_TYPE": "COHORTS",
13+
"COHORT_MEMBERSHIPS": [
14+
{
15+
"COHORT_LABEL": "rsv_80_since_02_Sept_2024",
16+
"DATE_JOINED": "20231020"
17+
}
18+
]
19+
},
20+
{
21+
"NHS_NUMBER": "9658218873",
22+
"ATTRIBUTE_TYPE": "PERSON",
23+
"DATE_OF_BIRTH": "19500601",
24+
"GENDER": "2",
25+
"POSTCODE": "CB3 8DX",
26+
"POSTCODE_SECTOR": "CB38",
27+
"POSTCODE_OUTCODE": "CB3",
28+
"MSOA": "E02007085",
29+
"LSOA": "E01018223",
30+
"GP_PRACTICE_CODE": "D81046",
31+
"PCN": "U75549",
32+
"ICB": "QUE",
33+
"COMMISSIONING_REGION": "Y61",
34+
"13Q_FLAG": "N",
35+
"CARE_HOME_FLAG": "N",
36+
"DE_FLAG": "N"
37+
}
38+
]
39+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
{
2+
"scenario_name": "RSV - Vita Integration - Actionable - You should have the RSV vaccine ( existing NBS booking ) - empty cohorts - AmendNBS",
3+
"request_headers": {
4+
"nhs-login-nhs-number": "9658218881"
5+
},
6+
"config_filenames": [
7+
"vita_integration_test_config.json"
8+
],
9+
"data": [
10+
{
11+
"NHS_NUMBER": "9658218881",
12+
"ATTRIBUTE_TYPE": "PERSON",
13+
"DATE_OF_BIRTH": "19500601",
14+
"GENDER": "2",
15+
"POSTCODE": "CB3 8DX",
16+
"POSTCODE_SECTOR": "CB38",
17+
"POSTCODE_OUTCODE": "CB3",
18+
"MSOA": "E02007085",
19+
"LSOA": "E01018223",
20+
"GP_PRACTICE_CODE": "D81046",
21+
"PCN": "U75549",
22+
"ICB": "QUE",
23+
"COMMISSIONING_REGION": "Y61",
24+
"13Q_FLAG": "N",
25+
"CARE_HOME_FLAG": "N",
26+
"DE_FLAG": "N"
27+
},
28+
{
29+
"NHS_NUMBER": "9658218881",
30+
"ATTRIBUTE_TYPE": "RSV",
31+
"BOOKED_APPOINTMENT_DATE": "<<DATE_DAY_+720>>",
32+
"BOOKED_APPOINTMENT_PROVIDER": "NBS"
33+
}
34+
]
35+
}

0 commit comments

Comments
 (0)