Skip to content

Commit ba36b71

Browse files
[PRMP-388] Migration DynamoDB Step Function (#474)
Co-authored-by: PedroSoaresNHS <pedro.soares1@nhs.net>
1 parent 0e5bed9 commit ba36b71

File tree

1 file changed

+177
-0
lines changed

1 file changed

+177
-0
lines changed
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
# IAM Role for Step Functions
2+
3+
data "aws_iam_policy_document" "sfn_assume" {
4+
statement {
5+
effect = "Allow"
6+
actions = ["sts:AssumeRole"]
7+
principals {
8+
type = "Service"
9+
identifiers = ["states.amazonaws.com"]
10+
}
11+
}
12+
}
13+
14+
resource "aws_iam_role" "sfn_role" {
15+
name = "${terraform.workspace}_migration_sfn_role"
16+
assume_role_policy = data.aws_iam_policy_document.sfn_assume.json
17+
}
18+
19+
data "aws_iam_policy_document" "sfn_permissions" {
20+
# Invoke both Lambdas
21+
statement {
22+
effect = "Allow"
23+
actions = ["lambda:InvokeFunction"]
24+
resources = [
25+
module.migration-dynamodb-segment-lambda.lambda_arn,
26+
module.migration-dynamodb-lambda.lambda_arn
27+
]
28+
}
29+
30+
# S3 bucket-level permissions
31+
statement {
32+
effect = "Allow"
33+
actions = [
34+
"s3:ListBucket"
35+
]
36+
resources = [
37+
"arn:aws:s3:::${terraform.workspace}-${var.migration_dynamodb_segment_store_bucket_name}"
38+
]
39+
}
40+
41+
# S3 object-level permissions
42+
statement {
43+
effect = "Allow"
44+
actions = [
45+
"s3:GetObject"
46+
]
47+
resources = [
48+
"arn:aws:s3:::${terraform.workspace}-${var.migration_dynamodb_segment_store_bucket_name}/*"
49+
]
50+
}
51+
52+
# Distributed Map child executions
53+
statement {
54+
effect = "Allow"
55+
actions = [
56+
"states:StartExecution",
57+
"states:DescribeExecution",
58+
"states:StopExecution",
59+
"states:GetExecutionHistory",
60+
"states:ListExecutions",
61+
"states:DescribeMapRun",
62+
"states:ListMapRuns"
63+
]
64+
resources = [
65+
"arn:aws:states:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:stateMachine:${terraform.workspace}_migration_dynamodb_step_function",
66+
"arn:aws:states:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:execution:${terraform.workspace}_migration_dynamodb_step_function/*",
67+
"arn:aws:states:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:mapRun:${terraform.workspace}_migration_dynamodb_step_function/*"
68+
]
69+
}
70+
71+
# CloudWatch Logs delivery
72+
statement {
73+
effect = "Allow"
74+
actions = [
75+
"logs:CreateLogDelivery",
76+
"logs:GetLogDelivery",
77+
"logs:UpdateLogDelivery",
78+
"logs:DeleteLogDelivery",
79+
"logs:ListLogDeliveries",
80+
"logs:PutResourcePolicy",
81+
"logs:DescribeResourcePolicies",
82+
"logs:DescribeLogGroups"
83+
]
84+
resources = ["*"]
85+
}
86+
}
87+
88+
resource "aws_iam_role_policy" "sfn_policy" {
89+
name = "${terraform.workspace}_migration_sfn_policy"
90+
role = aws_iam_role.sfn_role.id
91+
policy = data.aws_iam_policy_document.sfn_permissions.json
92+
}
93+
94+
# Step Function Definition
95+
96+
resource "aws_sfn_state_machine" "migration_dynamodb" {
97+
name = "${terraform.workspace}_migration_dynamodb_step_function"
98+
role_arn = aws_iam_role.sfn_role.arn
99+
100+
definition = jsonencode({
101+
StartAt = "Segment Creator",
102+
States = {
103+
"Segment Creator" = {
104+
Type = "Task",
105+
Resource = "arn:aws:states:::lambda:invoke",
106+
Parameters = {
107+
"FunctionName" = module.migration-dynamodb-segment-lambda.lambda_arn,
108+
"Payload" = {
109+
"totalSegments.$" = "$.totalSegments",
110+
"tableArn.$" = "$.tableArn",
111+
"executionId.$" = "$$.Execution.Id"
112+
}
113+
},
114+
ResultSelector = {
115+
"bucket.$" = "$.Payload.bucket",
116+
"key.$" = "$.Payload.key"
117+
},
118+
ResultPath = "$.SegmentSource",
119+
Next = "Segment Map (Distributed)"
120+
},
121+
122+
"Segment Map (Distributed)" = {
123+
Type = "Map",
124+
MaxConcurrency = 100,
125+
126+
ItemReader = {
127+
Resource = "arn:aws:states:::s3:getObject",
128+
ReaderConfig = {
129+
InputType = "JSON"
130+
},
131+
Parameters = {
132+
"Bucket.$" = "$.SegmentSource.bucket",
133+
"Key.$" = "$.SegmentSource.key"
134+
}
135+
},
136+
137+
ItemSelector = {
138+
"segment.$" = "$$.Map.Item.Value",
139+
"totalSegments.$" = "$.totalSegments",
140+
"tableArn.$" = "$.tableArn",
141+
"migrationScript.$" = "$.migrationScript",
142+
"run_migration.$" = "$.run_migration",
143+
"execution_Id.$" = "$$.Execution.Id"
144+
},
145+
146+
ItemProcessor = {
147+
ProcessorConfig = {
148+
Mode = "DISTRIBUTED",
149+
ExecutionType = "STANDARD"
150+
},
151+
StartAt = "Run DynamoDB Migration",
152+
States = {
153+
"Run DynamoDB Migration" = {
154+
Type = "Task",
155+
Resource = "arn:aws:states:::lambda:invoke",
156+
Parameters = {
157+
FunctionName = module.migration-dynamodb-lambda.lambda_arn,
158+
"Payload" = {
159+
"segment.$" = "$.segment",
160+
"totalSegments.$" = "$.totalSegments",
161+
"tableArn.$" = "$.tableArn",
162+
"migrationScript.$" = "$.migrationScript",
163+
"run_migration.$" = "$.run_migration",
164+
"execution_Id.$" = "$.execution_Id"
165+
}
166+
},
167+
ResultSelector = { "migrationResult.$" = "$.Payload" },
168+
ResultPath = "$.MigrationResult",
169+
End = true
170+
}
171+
}
172+
},
173+
End = true
174+
}
175+
}
176+
})
177+
}

0 commit comments

Comments
 (0)