-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add
GuFastlyKinesisLogRoleExperimental
role (#1750)
- Loading branch information
Showing
11 changed files
with
330 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
/** | ||
* Fastly's AWS account ID. | ||
* This is needed by IAM roles assumed by Fastly in order to write into | ||
* an S3 bucket or a Kinesis stream. | ||
* See https://docs.fastly.com/en/guides/creating-an-aws-iam-role-for-fastly-logging | ||
*/ | ||
export const FASTLY_AWS_ACCOUNT_ID = "717331877981"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from "./roles"; |
170 changes: 170 additions & 0 deletions
170
src/experimental/constructs/iam/roles/__snapshots__/fastly-kinesis-log.test.ts.snap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
// Jest Snapshot v1, https://goo.gl/fbAQLP | ||
|
||
exports[`The GuFastlyKinesisLogRole construct correctly wires up the policy 1`] = ` | ||
{ | ||
"Conditions": { | ||
"AwsCdkKinesisEncryptedStreamsUnsupportedRegions": { | ||
"Fn::Or": [ | ||
{ | ||
"Fn::Equals": [ | ||
{ | ||
"Ref": "AWS::Region", | ||
}, | ||
"cn-north-1", | ||
], | ||
}, | ||
{ | ||
"Fn::Equals": [ | ||
{ | ||
"Ref": "AWS::Region", | ||
}, | ||
"cn-northwest-1", | ||
], | ||
}, | ||
], | ||
}, | ||
}, | ||
"Metadata": { | ||
"gu:cdk:constructs": [ | ||
"GuStack", | ||
"GuKinesisStream", | ||
"GuFastlyCustomerIdParameter", | ||
"GuFastlyKinesisLogRoleExperimental", | ||
"GuKinesisPutRecordsPolicyExperimental", | ||
], | ||
"gu:cdk:version": "TEST", | ||
}, | ||
"Parameters": { | ||
"FastlyCustomerId": { | ||
"Default": "/account/external/fastly/customer.id", | ||
"Description": "SSM parameter containing the Fastly Customer ID. Can be obtained from https://manage.fastly.com/account/company by an admin", | ||
"Type": "AWS::SSM::Parameter::Value<String>", | ||
}, | ||
}, | ||
"Resources": { | ||
"GuKinesisPutRecordsPolicy28D5CD2D": { | ||
"Properties": { | ||
"PolicyDocument": { | ||
"Statement": [ | ||
{ | ||
"Action": [ | ||
"kinesis:PutRecords", | ||
"kinesis:ListShards", | ||
], | ||
"Effect": "Allow", | ||
"Resource": { | ||
"Fn::GetAtt": [ | ||
"testStream8BCA7523", | ||
"Arn", | ||
], | ||
}, | ||
}, | ||
], | ||
"Version": "2012-10-17", | ||
}, | ||
"PolicyName": "GuKinesisPutRecordsPolicy28D5CD2D", | ||
"Roles": [ | ||
{ | ||
"Ref": "testKinesisLogRole5E3B33EE", | ||
}, | ||
], | ||
}, | ||
"Type": "AWS::IAM::Policy", | ||
}, | ||
"testKinesisLogRole5E3B33EE": { | ||
"Properties": { | ||
"AssumeRolePolicyDocument": { | ||
"Statement": [ | ||
{ | ||
"Action": "sts:AssumeRole", | ||
"Condition": { | ||
"StringEquals": { | ||
"sts:ExternalId": { | ||
"Ref": "FastlyCustomerId", | ||
}, | ||
}, | ||
}, | ||
"Effect": "Allow", | ||
"Principal": { | ||
"AWS": { | ||
"Fn::Join": [ | ||
"", | ||
[ | ||
"arn:", | ||
{ | ||
"Ref": "AWS::Partition", | ||
}, | ||
":iam::717331877981:root", | ||
], | ||
], | ||
}, | ||
}, | ||
}, | ||
], | ||
"Version": "2012-10-17", | ||
}, | ||
"RoleName": "writeToKinesisRoleTest", | ||
"Tags": [ | ||
{ | ||
"Key": "gu:cdk:version", | ||
"Value": "TEST", | ||
}, | ||
{ | ||
"Key": "gu:repo", | ||
"Value": "guardian/cdk", | ||
}, | ||
{ | ||
"Key": "Stack", | ||
"Value": "test-stack", | ||
}, | ||
{ | ||
"Key": "Stage", | ||
"Value": "TEST", | ||
}, | ||
], | ||
}, | ||
"Type": "AWS::IAM::Role", | ||
}, | ||
"testStream8BCA7523": { | ||
"Properties": { | ||
"RetentionPeriodHours": 24, | ||
"ShardCount": 1, | ||
"StreamEncryption": { | ||
"Fn::If": [ | ||
"AwsCdkKinesisEncryptedStreamsUnsupportedRegions", | ||
{ | ||
"Ref": "AWS::NoValue", | ||
}, | ||
{ | ||
"EncryptionType": "KMS", | ||
"KeyId": "alias/aws/kinesis", | ||
}, | ||
], | ||
}, | ||
"StreamModeDetails": { | ||
"StreamMode": "PROVISIONED", | ||
}, | ||
"Tags": [ | ||
{ | ||
"Key": "gu:cdk:version", | ||
"Value": "TEST", | ||
}, | ||
{ | ||
"Key": "gu:repo", | ||
"Value": "guardian/cdk", | ||
}, | ||
{ | ||
"Key": "Stack", | ||
"Value": "test-stack", | ||
}, | ||
{ | ||
"Key": "Stage", | ||
"Value": "TEST", | ||
}, | ||
], | ||
}, | ||
"Type": "AWS::Kinesis::Stream", | ||
}, | ||
}, | ||
} | ||
`; |
59 changes: 59 additions & 0 deletions
59
src/experimental/constructs/iam/roles/fastly-kinesis-log.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import { Template } from "aws-cdk-lib/assertions"; | ||
import { FASTLY_AWS_ACCOUNT_ID } from "../../../../constants"; | ||
import { GuKinesisStream } from "../../../../constructs/kinesis"; | ||
import { simpleGuStackForTesting } from "../../../../utils/test"; | ||
import { GuFastlyKinesisLogRoleExperimental } from "./fastly-kinesis-log"; | ||
|
||
describe("The GuFastlyKinesisLogRole construct", () => { | ||
it("correctly wires up the policy", () => { | ||
const stack = simpleGuStackForTesting(); | ||
const testStream = new GuKinesisStream(stack, "testStream"); | ||
new GuFastlyKinesisLogRoleExperimental(stack, "testKinesisLogRole", { | ||
stream: testStream, | ||
roleName: "writeToKinesisRoleTest", | ||
}); | ||
expect(Template.fromStack(stack).toJSON()).toMatchSnapshot(); | ||
}); | ||
|
||
it("assumes the correct role", () => { | ||
const stack = simpleGuStackForTesting(); | ||
const testStream = new GuKinesisStream(stack, "testStream"); | ||
new GuFastlyKinesisLogRoleExperimental(stack, "testKinesisLogRole", { | ||
stream: testStream, | ||
roleName: "writeToKinesisRoleTest", | ||
}); | ||
|
||
Template.fromStack(stack).hasResourceProperties("AWS::IAM::Role", { | ||
AssumeRolePolicyDocument: { | ||
Version: "2012-10-17", | ||
Statement: [ | ||
{ | ||
Action: "sts:AssumeRole", | ||
Condition: { | ||
StringEquals: { | ||
"sts:ExternalId": { | ||
Ref: "FastlyCustomerId", | ||
}, | ||
}, | ||
}, | ||
Effect: "Allow", | ||
Principal: { | ||
AWS: { | ||
"Fn::Join": [ | ||
"", | ||
[ | ||
"arn:", | ||
{ | ||
Ref: "AWS::Partition", | ||
}, | ||
`:iam::${FASTLY_AWS_ACCOUNT_ID}:root`, | ||
], | ||
], | ||
}, | ||
}, | ||
}, | ||
], | ||
}, | ||
}); | ||
}); | ||
}); |
46 changes: 46 additions & 0 deletions
46
src/experimental/constructs/iam/roles/fastly-kinesis-log.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import { AccountPrincipal } from "aws-cdk-lib/aws-iam"; | ||
import { FASTLY_AWS_ACCOUNT_ID } from "../../../../constants/fastly-aws-account-id"; | ||
import type { GuStack } from "../../../../constructs/core"; | ||
import { GuFastlyCustomerIdParameter } from "../../../../constructs/core"; | ||
import { GuRole } from "../../../../constructs/iam"; | ||
import type { GuKinesisStream } from "../../../../constructs/kinesis"; | ||
import { GuKinesisPutRecordsPolicyExperimental } from "../../policies/kinesis-put-records"; | ||
|
||
export interface GuFastlyKinesisLogRoleProps { | ||
/** | ||
* The Kinesis stream into which Fastly will put records | ||
*/ | ||
stream: GuKinesisStream; | ||
/** | ||
* Name of the IAM role | ||
*/ | ||
roleName?: string; | ||
} | ||
|
||
/** | ||
* A construct to create an IAM Role for Fastly to assume in order to write to a | ||
* specific Kinesis stream. | ||
* | ||
* In order to use this construct, an SSM parameter named `/account/external/fastly/customer.id` | ||
* needs to exist in the AWS account's parameter store, and the value should be | ||
* the Guardian's Fastly customer id. | ||
* | ||
*/ | ||
export class GuFastlyKinesisLogRoleExperimental extends GuRole { | ||
constructor(scope: GuStack, id: string, props: GuFastlyKinesisLogRoleProps) { | ||
const fastlyCustomerId = GuFastlyCustomerIdParameter.getInstance(scope).valueAsString; | ||
const { roleName, stream } = props; | ||
|
||
super(scope, id, { | ||
roleName, | ||
assumedBy: new AccountPrincipal(FASTLY_AWS_ACCOUNT_ID), | ||
externalIds: [fastlyCustomerId], | ||
}); | ||
|
||
const policy = new GuKinesisPutRecordsPolicyExperimental(scope, "GuKinesisPutRecordsPolicy", { | ||
stream, | ||
}); | ||
|
||
policy.attachToRole(this); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from "./fastly-kinesis-log"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from "./kinesis-put-records"; |
28 changes: 28 additions & 0 deletions
28
src/experimental/constructs/policies/kinesis-put-records.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import { Template } from "aws-cdk-lib/assertions"; | ||
import { GuKinesisStream } from "../../../constructs/kinesis"; | ||
import { attachPolicyToTestRole, simpleGuStackForTesting } from "../../../utils/test"; | ||
import { GuKinesisPutRecordsPolicyExperimental } from "./kinesis-put-records"; | ||
|
||
describe("The GuKinesisPutRecordsPolicy class", () => { | ||
it("has the correct action permissions", () => { | ||
const stack = simpleGuStackForTesting(); | ||
const stream = new GuKinesisStream(stack, "testStream"); | ||
|
||
const kinesisPutRecordsPolicy = new GuKinesisPutRecordsPolicyExperimental(stack, "KinesisPolicy", { stream }); | ||
|
||
attachPolicyToTestRole(stack, kinesisPutRecordsPolicy); | ||
|
||
Template.fromStack(stack).hasResourceProperties("AWS::IAM::Policy", { | ||
PolicyDocument: { | ||
Version: "2012-10-17", | ||
Statement: [ | ||
{ | ||
Effect: "Allow", | ||
Action: ["kinesis:PutRecords", "kinesis:ListShards"], | ||
Resource: { "Fn::GetAtt": ["testStream8BCA7523", "Arn"] }, | ||
}, | ||
], | ||
}, | ||
}); | ||
}); | ||
}); |
15 changes: 15 additions & 0 deletions
15
src/experimental/constructs/policies/kinesis-put-records.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import type { GuStack } from "../../../constructs/core"; | ||
import type { GuNoStatementsPolicyProps } from "../../../constructs/iam/policies/base-policy"; | ||
import { GuAllowPolicy } from "../../../constructs/iam/policies/base-policy"; | ||
import type { GuKinesisStream } from "../../../constructs/kinesis"; | ||
|
||
export interface GuKinesisPutRecordsPolicyProps extends GuNoStatementsPolicyProps { | ||
stream: GuKinesisStream; | ||
} | ||
|
||
export class GuKinesisPutRecordsPolicyExperimental extends GuAllowPolicy { | ||
constructor(scope: GuStack, id: string, props: GuKinesisPutRecordsPolicyProps) { | ||
const { stream } = props; | ||
super(scope, id, { actions: ["kinesis:PutRecords", "kinesis:ListShards"], resources: [stream.streamArn] }); | ||
} | ||
} |