-
Notifications
You must be signed in to change notification settings - Fork 4.3k
feat(stepfunctions-tasks): add EKS call to SFN-tasks #12779
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
ea41033
d6d55e5
fb639aa
b831188
26150b4
db84626
6f545ed
5796a70
1130675
af0dee4
b5556e9
453bd85
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,125 @@ | ||
| import * as iam from '@aws-cdk/aws-iam'; | ||
| import * as sfn from '@aws-cdk/aws-stepfunctions'; | ||
| import { Construct } from 'constructs'; | ||
| import { integrationResourceArn, validatePatternSupported } from '../private/task-utils'; | ||
|
|
||
| /** | ||
| * Properties for calling a EKS endpoint with EksCall | ||
| */ | ||
| export interface EksCallProps extends sfn.TaskStateBaseProps { | ||
|
|
||
| /** | ||
| * Name of the cluster | ||
| */ | ||
| readonly clusterName: string; | ||
|
|
||
| /** | ||
| * Base 64 encoded certificate data required to communicate with your cluster | ||
| */ | ||
| readonly certificateAuthority: string; | ||
|
||
|
|
||
| /** | ||
| * API endpoint to communicate with your cluster | ||
| */ | ||
| readonly endpoint: string; | ||
|
||
|
|
||
| /** | ||
| * HTTP method ("GET", "POST", "PUT", ...) part of HTTP request | ||
| */ | ||
| readonly httpMethod: MethodType; | ||
|
|
||
| /** | ||
| * Path of cluster | ||
| */ | ||
| readonly path: string; | ||
|
|
||
| /** | ||
| * Query Parameters part of HTTP request | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: would be helpful to include doc links and or purpose of query parameters. the current doc strings don't add much information from the parameter names
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Query parameters would look something like this: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#-strong-write-operations-cronjob-v1beta1-batch-strong- I'm not sure if it would be helpful to include an example such as this
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. gotcha, I agree. maybe using it in the readme example would be helpful for users though. |
||
| * @default - no query parameters | ||
| */ | ||
| readonly queryParameters?: { [key: string]: string[] }; | ||
|
|
||
| /** | ||
| * Request body part of HTTP request | ||
| * @default - No request body | ||
| */ | ||
| readonly requestBody?: { [key: string]: any }; | ||
|
||
| } | ||
|
|
||
| /** | ||
| * Call a EKS endpoint as a Task | ||
| * | ||
| * @see https://docs.aws.amazon.com/step-functions/latest/dg/connect-eks.html | ||
| */ | ||
| export class EksCall extends sfn.TaskStateBase { | ||
|
|
||
| private static readonly SUPPORTED_INTEGRATION_PATTERNS: sfn.IntegrationPattern[] = [ | ||
| sfn.IntegrationPattern.REQUEST_RESPONSE, | ||
| ]; | ||
|
|
||
| protected readonly taskMetrics?: sfn.TaskMetricsConfig; | ||
| protected readonly taskPolicies?: iam.PolicyStatement[]; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. probably worth a comment why task policies are not being set in this integration
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added a comment in latest commit. |
||
|
|
||
| private readonly integrationPattern: sfn.IntegrationPattern; | ||
|
|
||
| constructor(scope: Construct, id: string, private readonly props: EksCallProps) { | ||
| super(scope, id, props); | ||
| this.integrationPattern = props.integrationPattern ?? sfn.IntegrationPattern.REQUEST_RESPONSE; | ||
|
|
||
| validatePatternSupported(this.integrationPattern, EksCall.SUPPORTED_INTEGRATION_PATTERNS); | ||
| } | ||
|
|
||
| /** | ||
| * Provides the EKS Call service integration task configuration | ||
| * @internal | ||
| */ | ||
| protected _renderTask(): any { | ||
| return { | ||
| Resource: integrationResourceArn('eks', 'call', this.integrationPattern), | ||
| Parameters: sfn.FieldUtils.renderObject({ | ||
| ClusterName: this.props.clusterName, | ||
| CertificateAuthority: this.props.certificateAuthority, | ||
| Endpoint: this.props.endpoint, | ||
| Method: this.props.httpMethod, | ||
| Path: this.props.path, | ||
| QueryParameters: this.props.queryParameters, | ||
| RequestBody: this.props.requestBody, | ||
| }), | ||
| }; | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Method type of a EKS call | ||
| */ | ||
| export enum MethodType { | ||
|
||
| /** | ||
| * Retrieve data from a server at the specified resource | ||
| */ | ||
| GET = 'GET', | ||
|
|
||
| /** | ||
| * Send data to the API endpoint to create or update a resource | ||
| */ | ||
| POST = 'POST', | ||
|
|
||
| /** | ||
| * Send data to the API endpoint to update or create a resource | ||
| */ | ||
| PUT = 'PUT', | ||
|
|
||
| /** | ||
| * Delete the resource at the specified endpoint | ||
| */ | ||
| DELETE = 'DELETE', | ||
|
|
||
| /** | ||
| * Apply partial modifications to the resource | ||
| */ | ||
| PATCH = 'PATCH', | ||
|
|
||
| /** | ||
| * Retrieve data from a server at the specified resource without the response body | ||
| */ | ||
| HEAD = 'HEAD' | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| import * as sfn from '@aws-cdk/aws-stepfunctions'; | ||
| import * as cdk from '@aws-cdk/core'; | ||
| import { EksCall, MethodType } from '../../lib/eks/call'; | ||
|
|
||
| describe('Call an EKS endpoint', () => { | ||
|
||
|
|
||
| test('default settings', () => { | ||
| // GIVEN | ||
| const stack = new cdk.Stack(); | ||
|
|
||
| // WHEN | ||
| const task = new EksCall(stack, 'Call', { | ||
| clusterName: 'clusterName', | ||
| certificateAuthority: 'certificateAuthority', | ||
| endpoint: 'endpoint', | ||
| httpMethod: MethodType.GET, | ||
| path: 'path', | ||
| requestBody: sfn.TaskInput.fromObject({ | ||
| RequestBody: 'requestBody', | ||
| }), | ||
| }); | ||
|
|
||
| // THEN | ||
| expect(stack.resolve(task.toStateJson())).toEqual({ | ||
| Type: 'Task', | ||
| Resource: { | ||
| 'Fn::Join': [ | ||
| '', | ||
| [ | ||
| 'arn:', | ||
| { | ||
| Ref: 'AWS::Partition', | ||
| }, | ||
| ':states:::eks:call', | ||
| ], | ||
| ], | ||
| }, | ||
| End: true, | ||
| Parameters: { | ||
| ClusterName: 'clusterName', | ||
| CertificateAuthority: 'certificateAuthority', | ||
| Endpoint: 'endpoint', | ||
| Method: 'GET', | ||
| Path: 'path', | ||
| RequestBody: { | ||
| type: 1, | ||
| value: { | ||
| RequestBody: 'requestBody', | ||
| }, | ||
| }, | ||
| }, | ||
| }); | ||
| }); | ||
| }); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,65 @@ | ||
| { | ||
| "Resources": { | ||
| "StateMachineRoleB840431D": { | ||
| "Type": "AWS::IAM::Role", | ||
| "Properties": { | ||
| "AssumeRolePolicyDocument": { | ||
| "Statement": [ | ||
| { | ||
| "Action": "sts:AssumeRole", | ||
| "Effect": "Allow", | ||
| "Principal": { | ||
| "Service": { | ||
| "Fn::Join": [ | ||
| "", | ||
| [ | ||
| "states.", | ||
| { | ||
| "Ref": "AWS::Region" | ||
| }, | ||
| ".amazonaws.com" | ||
| ] | ||
| ] | ||
| } | ||
| } | ||
| } | ||
| ], | ||
| "Version": "2012-10-17" | ||
| } | ||
| } | ||
| }, | ||
| "StateMachine2E01A3A5": { | ||
| "Type": "AWS::StepFunctions::StateMachine", | ||
| "Properties": { | ||
| "RoleArn": { | ||
| "Fn::GetAtt": [ | ||
| "StateMachineRoleB840431D", | ||
| "Arn" | ||
| ] | ||
| }, | ||
| "DefinitionString": { | ||
| "Fn::Join": [ | ||
| "", | ||
| [ | ||
| "{\"StartAt\":\"Call a EKS Endpoint\",\"States\":{\"Call a EKS Endpoint\":{\"End\":true,\"Type\":\"Task\",\"Resource\":\"arn:", | ||
| { | ||
| "Ref": "AWS::Partition" | ||
| }, | ||
| ":states:::eks:call\",\"Parameters\":{\"ClusterName\":\"clusterName\",\"CertificateAuthority\":\"certificateAuthority\",\"Endpoint\":\"https://apiid.gr7.us-east-1.eks.amazonaws.com\",\"Method\":\"GET\",\"Path\":\"/api/v1/namespaces/default/pods\"}}},\"TimeoutSeconds\":30}" | ||
| ] | ||
| ] | ||
| } | ||
| }, | ||
| "DependsOn": [ | ||
| "StateMachineRoleB840431D" | ||
| ] | ||
| } | ||
| }, | ||
| "Outputs": { | ||
| "stateMachineArn": { | ||
| "Value": { | ||
| "Ref": "StateMachine2E01A3A5" | ||
| } | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| import * as sfn from '@aws-cdk/aws-stepfunctions'; | ||
| import * as cdk from '@aws-cdk/core'; | ||
| import { EksCall, MethodType } from '../../lib'; | ||
|
|
||
| const app = new cdk.App(); | ||
| const stack = new cdk.Stack(app, 'aws-stepfunctions-tasks-eks-call-integ'); | ||
|
Comment on lines
+18
to
+20
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this test is not self contained. Please include verification steps, but more importantly create the EKS cluster as a part of the integration test. The test should create a state machine that can be executed successfully. Right now it has a dependency that an EKS job already exists called Verification steps should look something like this
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Modified integ test in the latest commit |
||
|
|
||
| const callJob = new EksCall(stack, 'Call a EKS Endpoint', { | ||
| clusterName: 'clusterName', | ||
| certificateAuthority: 'certificateAuthority', | ||
| endpoint: 'https://apiid.gr7.us-east-1.eks.amazonaws.com', | ||
| httpMethod: MethodType.GET, | ||
| path: '/api/v1/namespaces/default/pods', | ||
| }); | ||
|
|
||
| const chain = sfn.Chain.start(callJob); | ||
|
|
||
| const sm = new sfn.StateMachine(stack, 'StateMachine', { | ||
| definition: chain, | ||
| timeout: cdk.Duration.seconds(30), | ||
| }); | ||
|
|
||
| new cdk.CfnOutput(stack, 'stateMachineArn', { | ||
| value: sm.stateMachineArn, | ||
| }); | ||
|
|
||
|
|
||
| app.synth(); | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not take in an
IClusterand take properties out of it?question: are step functions executions of EKS restricted to the account in which the state machine resides?
this is available as
clusterNamein anIClusterThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will use EKS L2 Construct instead in next commit.