Skip to content

Commit

Permalink
feat(codeguruprofiler): ProfilingGroup (#7895)
Browse files Browse the repository at this point in the history
fixes #6984 by creating L2 construct and functions to allow for policies to be assigned to execution roles.

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
SeekerWing authored May 26, 2020
1 parent 44e4d66 commit 995088a
Show file tree
Hide file tree
Showing 7 changed files with 758 additions and 2 deletions.
20 changes: 19 additions & 1 deletion packages/@aws-cdk/aws-codeguruprofiler/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,26 @@
---
<!--END STABILITY BANNER-->

This module is part of the [AWS Cloud Development Kit](https://github.com/aws/aws-cdk) project.
Amazon CodeGuru Profiler collects runtime performance data from your live applications, and provides recommendations that can help you fine-tune your application performance.

### Installation

Import to your project:

```ts
import * as codeguruprofiler from '@aws-cdk/aws-codeguruprofiler';
```

### Basic usage

Here's how to setup a profiling group and give your compute role permissions to publish to the profiling group to the profiling agent can publish profiling information:

```ts
// The execution role of your application that publishes to the ProfilingGroup via CodeGuru Profiler Profiling Agent. (the following is merely an example)
const publishAppRole = new Role(stack, 'PublishAppRole', {
assumedBy: new AccountRootPrincipal(),
});

const profilingGroup = new ProfilingGroup(stack, 'MyProfilingGroup');
profilingGroup.grantPublish(publishAppRole);
```
1 change: 1 addition & 0 deletions packages/@aws-cdk/aws-codeguruprofiler/lib/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
// AWS::CodeGuruProfiler CloudFormation Resources:
export * from './codeguruprofiler.generated';
export * from './profiling-group';
180 changes: 180 additions & 0 deletions packages/@aws-cdk/aws-codeguruprofiler/lib/profiling-group.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
import { Grant, IGrantable } from '@aws-cdk/aws-iam';
import { Construct, IResource, Lazy, Resource, Stack } from '@aws-cdk/core';
import { CfnProfilingGroup } from './codeguruprofiler.generated';

/**
* IResource represents a Profiling Group.
*/
export interface IProfilingGroup extends IResource {

/**
* A name for the profiling group.
*
* @attribute
*/
readonly profilingGroupName: string;

/**
* Grant access to publish profiling information to the Profiling Group to the given identity.
*
* This will grant the following permissions:
*
* - codeguru-profiler:ConfigureAgent
* - codeguru-profiler:PostAgentProfile
*
* @param grantee Principal to grant publish rights to
*/
grantPublish(grantee: IGrantable): Grant;

/**
* Grant access to read profiling information from the Profiling Group to the given identity.
*
* This will grant the following permissions:
*
* - codeguru-profiler:GetProfile
* - codeguru-profiler:DescribeProfilingGroup
*
* @param grantee Principal to grant read rights to
*/
grantRead(grantee: IGrantable): Grant;

}

abstract class ProfilingGroupBase extends Resource implements IProfilingGroup {

public abstract readonly profilingGroupName: string;

public abstract readonly profilingGroupArn: string;

/**
* Grant access to publish profiling information to the Profiling Group to the given identity.
*
* This will grant the following permissions:
*
* - codeguru-profiler:ConfigureAgent
* - codeguru-profiler:PostAgentProfile
*
* @param grantee Principal to grant publish rights to
*/
public grantPublish(grantee: IGrantable) {
// https://docs.aws.amazon.com/codeguru/latest/profiler-ug/security-iam.html#security-iam-access-control
return Grant.addToPrincipal({
grantee,
actions: ['codeguru-profiler:ConfigureAgent', 'codeguru-profiler:PostAgentProfile'],
resourceArns: [this.profilingGroupArn],
});
}

/**
* Grant access to read profiling information from the Profiling Group to the given identity.
*
* This will grant the following permissions:
*
* - codeguru-profiler:GetProfile
* - codeguru-profiler:DescribeProfilingGroup
*
* @param grantee Principal to grant read rights to
*/
public grantRead(grantee: IGrantable) {
// https://docs.aws.amazon.com/codeguru/latest/profiler-ug/security-iam.html#security-iam-access-control
return Grant.addToPrincipal({
grantee,
actions: ['codeguru-profiler:GetProfile', 'codeguru-profiler:DescribeProfilingGroup'],
resourceArns: [this.profilingGroupArn],
});
}

}

/**
* Properties for creating a new Profiling Group.
*/
export interface ProfilingGroupProps {

/**
* A name for the profiling group.
* @default - automatically generated name.
*/
readonly profilingGroupName?: string;

}

/**
* A new Profiling Group.
*/
export class ProfilingGroup extends ProfilingGroupBase {

/**
* Import an existing Profiling Group provided a Profiling Group Name.
*
* @param scope The parent creating construct
* @param id The construct's name
* @param profilingGroupName Profiling Group Name
*/
public static fromProfilingGroupName(scope: Construct, id: string, profilingGroupName: string): IProfilingGroup {
const stack = Stack.of(scope);

return this.fromProfilingGroupArn(scope, id, stack.formatArn({
service: 'codeguru-profiler',
resource: 'profilingGroup',
resourceName: profilingGroupName,
}));
}

/**
* Import an existing Profiling Group provided an ARN.
*
* @param scope The parent creating construct
* @param id The construct's name
* @param profilingGroupArn Profiling Group ARN
*/
public static fromProfilingGroupArn(scope: Construct, id: string, profilingGroupArn: string): IProfilingGroup {
class Import extends ProfilingGroupBase {
public readonly profilingGroupName = Stack.of(scope).parseArn(profilingGroupArn).resource;
public readonly profilingGroupArn = profilingGroupArn;
}

return new Import(scope, id);
}

/**
* The name of the Profiling Group.
*
* @attribute
*/
public readonly profilingGroupName: string;

/**
* The ARN of the Profiling Group.
*
* @attribute
*/
public readonly profilingGroupArn: string;

constructor(scope: Construct, id: string, props: ProfilingGroupProps = {}) {
super(scope, id, {
physicalName: props.profilingGroupName ?? Lazy.stringValue({ produce: () => this.generateUniqueId() }),
});

const profilingGroup = new CfnProfilingGroup(this, 'ProfilingGroup', {
profilingGroupName: this.physicalName,
});

this.profilingGroupName = this.getResourceNameAttribute(profilingGroup.ref);

this.profilingGroupArn = this.getResourceArnAttribute(profilingGroup.attrArn, {
service: 'codeguru-profiler',
resource: 'profilingGroup',
resourceName: this.physicalName,
});
}

private generateUniqueId(): string {
const name = this.node.uniqueId;
if (name.length > 240) {
return name.substring(0, 120) + name.substring(name.length - 120);
}
return name;
}

}
6 changes: 5 additions & 1 deletion packages/@aws-cdk/aws-codeguruprofiler/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,18 @@
"devDependencies": {
"@aws-cdk/assert": "0.0.0",
"cdk-build-tools": "0.0.0",
"cdk-integ-tools": "0.0.0",
"cfn2ts": "0.0.0",
"pkglint": "0.0.0"
},
"dependencies": {
"@aws-cdk/aws-iam": "0.0.0",
"@aws-cdk/core": "0.0.0"
},
"peerDependencies": {
"@aws-cdk/core": "0.0.0"
"@aws-cdk/core": "0.0.0",
"@aws-cdk/aws-iam": "0.0.0",
"constructs": "^3.0.2"
},
"engines": {
"node": ">= 10.13.0 <13 || >=13.7.0"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
{
"Resources": {
"MyProfilingGroup829F0507": {
"Type": "AWS::CodeGuruProfiler::ProfilingGroup",
"Properties": {
"ProfilingGroupName": "ProfilerGroupIntegrationTestMyProfilingGroup81DA69A3"
}
},
"PublishAppRole9FEBD682": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"AWS": {
"Fn::Join": [
"",
[
"arn:",
{
"Ref": "AWS::Partition"
},
":iam::",
{
"Ref": "AWS::AccountId"
},
":root"
]
]
}
}
}
],
"Version": "2012-10-17"
}
}
},
"PublishAppRoleDefaultPolicyCA1E15C3": {
"Type": "AWS::IAM::Policy",
"Properties": {
"PolicyDocument": {
"Statement": [
{
"Action": [
"codeguru-profiler:ConfigureAgent",
"codeguru-profiler:PostAgentProfile"
],
"Effect": "Allow",
"Resource": {
"Fn::GetAtt": [
"MyProfilingGroup829F0507",
"Arn"
]
}
}
],
"Version": "2012-10-17"
},
"PolicyName": "PublishAppRoleDefaultPolicyCA1E15C3",
"Roles": [
{
"Ref": "PublishAppRole9FEBD682"
}
]
}
},
"ReadAppRole52FE6317": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"AWS": {
"Fn::Join": [
"",
[
"arn:",
{
"Ref": "AWS::Partition"
},
":iam::",
{
"Ref": "AWS::AccountId"
},
":root"
]
]
}
}
}
],
"Version": "2012-10-17"
}
}
},
"ReadAppRoleDefaultPolicy4BB8955C": {
"Type": "AWS::IAM::Policy",
"Properties": {
"PolicyDocument": {
"Statement": [
{
"Action": [
"codeguru-profiler:GetProfile",
"codeguru-profiler:DescribeProfilingGroup"
],
"Effect": "Allow",
"Resource": {
"Fn::GetAtt": [
"MyProfilingGroup829F0507",
"Arn"
]
}
}
],
"Version": "2012-10-17"
},
"PolicyName": "ReadAppRoleDefaultPolicy4BB8955C",
"Roles": [
{
"Ref": "ReadAppRole52FE6317"
}
]
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { AccountRootPrincipal, Role } from '@aws-cdk/aws-iam';
import { App, Stack, StackProps } from '@aws-cdk/core';
import { ProfilingGroup } from '../lib';

class ProfilerGroupIntegrationTest extends Stack {
constructor(scope: App, id: string, props?: StackProps) {
super(scope, id, props);

const profilingGroup = new ProfilingGroup(this, 'MyProfilingGroup');

const publishAppRole = new Role(this, 'PublishAppRole', {
assumedBy: new AccountRootPrincipal(),
});
profilingGroup.grantPublish(publishAppRole);

const readAppRole = new Role(this, 'ReadAppRole', {
assumedBy: new AccountRootPrincipal(),
});
profilingGroup.grantRead(readAppRole);

}
}

const app = new App();

new ProfilerGroupIntegrationTest(app, 'ProfilerGroupIntegrationTest');

app.synth();
Loading

0 comments on commit 995088a

Please sign in to comment.