Skip to content

Commit acb0975

Browse files
ELI-545 - service account
1 parent e2493b7 commit acb0975

File tree

2 files changed

+92
-0
lines changed

2 files changed

+92
-0
lines changed

infrastructure/stacks/api-layer/s3_buckets.tf

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,12 @@ module "s3_dq_metrics_bucket" {
5757
stack_name = local.stack_name
5858
workspace = terraform.workspace
5959
}
60+
61+
module "s3_athena_dq_query_bucket" {
62+
source = "../../modules/s3"
63+
bucket_name = "athena-stage"
64+
environment = var.environment
65+
project_name = var.project_name
66+
stack_name = local.stack_name
67+
workspace = terraform.workspace
68+
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
resource "aws_iam_user" "tableau_service" {
2+
name = "tableau-athena-service-account"
3+
}
4+
5+
resource "time_rotating" "athena_key_rotation" {
6+
rotation_days = 90
7+
}
8+
9+
resource "aws_iam_access_key" "tableau_key" {
10+
user = aws_iam_user.tableau_service.name
11+
12+
lifecycle {
13+
replace_triggered_by = [time_rotating.athena_key_rotation]
14+
}
15+
}
16+
17+
resource "aws_iam_user_policy" "tableau_athena_policy" {
18+
name = "TableauAthenaAccess"
19+
user = aws_iam_user.tableau_service.name
20+
21+
policy = jsonencode({
22+
Version = "2012-10-17"
23+
Statement = [
24+
{
25+
# 1. Essential Athena Query Actions
26+
Effect = "Allow"
27+
Action = [
28+
"athena:GetQueryExecution",
29+
"athena:GetQueryResults",
30+
"athena:StartQueryExecution",
31+
"athena:GetWorkGroup",
32+
"athena:StopQueryExecution",
33+
"athena:GetDataCatalog"
34+
]
35+
Resource = [
36+
"arn:aws:athena:${var.default_aws_region}:${data.aws_caller_identity.current.account_id}:workgroup/primary"
37+
]
38+
},
39+
{
40+
# 2. Metadata Discovery (The "Hidden" Glue Layer)
41+
Effect = "Allow"
42+
Action = [
43+
"glue:GetDatabase",
44+
"glue:GetTable",
45+
"glue:GetTables",
46+
"glue:GetDatabases"
47+
]
48+
Resource = [
49+
"arn:aws:glue:${var.default_aws_region}:${data.aws_caller_identity.current.account_id}:catalog",
50+
"arn:aws:glue:${var.default_aws_region}:${data.aws_caller_identity.current.account_id}:database/elid_db",
51+
"arn:aws:glue:${var.default_aws_region}:${data.aws_caller_identity.current.account_id}:table/elid_db/cohort_metrics"
52+
]
53+
},
54+
{
55+
# 3. Data Access (Your specific S3 bucket)
56+
Effect = "Allow"
57+
Action = [
58+
"s3:GetBucketLocation",
59+
"s3:GetObject",
60+
"s3:ListBucket"
61+
]
62+
Resource = [
63+
"arn:aws:s3:::${module.s3_dq_metrics_bucket.storage_bucket_name}",
64+
"arn:aws:s3:::${module.s3_dq_metrics_bucket.storage_bucket_name}/*"
65+
]
66+
},
67+
{
68+
# 4. Athena Results (The Staging Directory from your screenshot)
69+
Effect = "Allow"
70+
Action = [
71+
"s3:GetBucketLocation",
72+
"s3:GetObject",
73+
"s3:ListBucket",
74+
"s3:PutObject"
75+
]
76+
Resource = [
77+
"arn:aws:s3:::${module.s3_athena_dq_query_bucket.storage_bucket_name}",
78+
"arn:aws:s3:::${module.s3_athena_dq_query_bucket.storage_bucket_name}/*"
79+
]
80+
}
81+
]
82+
})
83+
}

0 commit comments

Comments
 (0)