Skip to content

Commit

Permalink
OPHYK-401 Create resources required by datantuonti process
Browse files Browse the repository at this point in the history
  • Loading branch information
tsu committed Jan 14, 2025
1 parent b0af10a commit fd8a2c5
Show file tree
Hide file tree
Showing 2 changed files with 123 additions and 0 deletions.
2 changes: 2 additions & 0 deletions infra/src/cdk-app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import * as path from "node:path";
import {createHealthCheckStacks} from "./health-check";
import {DatabaseBackupToS3} from "./DatabaseBackupToS3";
import {lookupAlarmTopic} from "./shared-account";
import {DatantuontiStack} from "./datantuonti";

class CdkApp extends cdk.App {
constructor(props: cdk.AppProps) {
Expand All @@ -34,6 +35,7 @@ class CdkApp extends cdk.App {
};

const ecsStack = new ECSStack(this, sharedAccount.prefix("ECSStack"), stackProps);
const datantuontiStack = new DatantuontiStack(this, sharedAccount.prefix("Datantuonti"), stackProps);
const databaseStack = new DatabaseStack(this, sharedAccount.prefix("Database"), ecsStack.cluster, stackProps);

createHealthCheckStacks(this)
Expand Down
121 changes: 121 additions & 0 deletions infra/src/datantuonti.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import * as cdk from "aws-cdk-lib";
import * as kms from "aws-cdk-lib/aws-kms";
import * as ssm from "aws-cdk-lib/aws-ssm";
import * as iam from "aws-cdk-lib/aws-iam";
import * as s3 from "aws-cdk-lib/aws-s3";
import * as constructs from "constructs";

export class DatantuontiStack extends cdk.Stack {
readonly exportBucket: s3.Bucket;
readonly encryptionKey: kms.Key;
readonly s3ImportRole: iam.Role;
readonly importPolicy: iam.Policy;

constructor(scope: constructs.Construct, id: string, props: cdk.StackProps) {
super(scope, id, props);

const _export = new Export(this, "Export");
this.exportBucket = _export.bucket;
this.encryptionKey = _export.encryptionKey;

const _import = new Import(this, "Import");
this.s3ImportRole = _import.role;
this.importPolicy = _import.policy;
}
}

class Export extends constructs.Construct {
readonly bucket: s3.Bucket;
readonly encryptionKey: kms.Key;

constructor(scope: constructs.Construct, id: string) {
super(scope, id);

const targetAccountPrincipal = this.createTargetAccountPrincipal();
this.bucket = this.createExportBucket(targetAccountPrincipal);
this.encryptionKey = this.createEncryptionKey(targetAccountPrincipal);
}

private createEncryptionKey(targetAccountPrincipal: iam.AccountPrincipal) {
const key = new kms.Key(this, "S3EncryptionKey", {
enableKeyRotation: true,
});

key.grantDecrypt(targetAccountPrincipal);

return key;
}

private createTargetAccountPrincipal() {
const targetAccountId = ssm.StringParameter.valueFromLookup(
this,
"oppijanumerorekisteri.tasks.datantuonti.export.role.target-account-id"
);

return new iam.AccountPrincipal(targetAccountId);
}

private createExportBucket(targetAccountPrincipal: iam.AccountPrincipal) {
const bucket = new s3.Bucket(this, "ExportBucket");

bucket.addLifecycleRule({
id: "DeleteDatantuontiObjectsAfterSevenDays",
enabled: true,
expiration: cdk.Duration.days(7),
prefix: "oppijanumerorekisteri/v1/csv/",
});
bucket.grantRead(targetAccountPrincipal);

return bucket;
}
}

class Import extends constructs.Construct {
readonly role: iam.Role;
readonly policy: iam.Policy;

constructor(scope: constructs.Construct, id: string) {
super(scope, id);

this.policy = this.createPolicy();
this.role = this.createRole(this.policy);
}

private createRole(policy: iam.Policy) {
const role = new iam.Role(this, "Role", {
assumedBy: new iam.ServicePrincipal("rds.amazonaws.com"),
});
policy.attachToRole(role);

return role;
}

private createPolicy() {
const importBucketName = ssm.StringParameter.valueFromLookup(
this,
"oppijanumerorekisteri.tasks.datantuonti.import.bucket.name"
);

const decryptionKeyArn = ssm.StringParameter.valueFromLookup(
this,
"oppijanumerorekisteri.tasks.datantuonti.import.bucket.decryption-key-arn"
);
const policy = new iam.Policy(this, "Import");

policy.addStatements(
new iam.PolicyStatement({
actions: ["s3:GetObject", "s3:ListBucket"],
resources: [
`arn:aws:s3:::${importBucketName}`,
`arn:aws:s3:::${importBucketName}/*`,
],
}),
new iam.PolicyStatement({
actions: ["kms:Decrypt"],
resources: [decryptionKeyArn],
})
);

return policy;
}
}

0 comments on commit fd8a2c5

Please sign in to comment.