diff --git a/.github/workflows/close-stale-prs.yml b/.github/workflows/close-stale-prs.yml index cd601426deba9..5eb104b04a417 100644 --- a/.github/workflows/close-stale-prs.yml +++ b/.github/workflows/close-stale-prs.yml @@ -11,7 +11,7 @@ jobs: pull-requests: write runs-on: ubuntu-latest steps: - - uses: rix0rrr/close-stale-prs@main + - uses: cdklabs/close-stale-prs@main with: # Required # Must be PROJEN_GITHUB_TOKEN because the default GHA GitHub token will not have permissions to diff --git a/.github/workflows/github-merit-badger.yml b/.github/workflows/github-merit-badger.yml index 0628aa33fb652..52fb16387ac6c 100644 --- a/.github/workflows/github-merit-badger.yml +++ b/.github/workflows/github-merit-badger.yml @@ -10,7 +10,7 @@ jobs: permissions: pull-requests: write steps: - - uses: aws-github-ops/github-merit-badger@main + - uses: cdklabs/github-merit-badger@main id: merit-badger with: github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/issue-reprioritization.yml b/.github/workflows/issue-reprioritization.yml index e8a68ec1276d1..8a3590c9ecc09 100644 --- a/.github/workflows/issue-reprioritization.yml +++ b/.github/workflows/issue-reprioritization.yml @@ -11,7 +11,7 @@ jobs: repository-projects: write runs-on: ubuntu-latest steps: - - uses: kaizencc/issue-reprioritization-manager@main + - uses: cdklabs/issue-reprioritization-manager@main id: reprioritization-manager with: github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/pr-labeler.yml b/.github/workflows/pr-labeler.yml index 1ce06fd16fcf1..f0757ded212b9 100644 --- a/.github/workflows/pr-labeler.yml +++ b/.github/workflows/pr-labeler.yml @@ -24,7 +24,7 @@ jobs: permissions: pull-requests: write steps: - - uses: kaizencc/pr-triage-manager@main + - uses: cdklabs/pr-triage-manager@main with: github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/pr-linter-exemption-labeler.yml b/.github/workflows/pr-linter-exemption-labeler.yml index 332a216a6811e..878d90d3f2ffc 100644 --- a/.github/workflows/pr-linter-exemption-labeler.yml +++ b/.github/workflows/pr-linter-exemption-labeler.yml @@ -12,6 +12,6 @@ jobs: if: ${{ (github.event.issue.pull_request) && (github.event.issue.state == 'open') }} runs-on: ubuntu-latest steps: - - uses: TheRealAmazonKendra/pr-linter-exemption-labeler@main + - uses: cdklabs/pr-linter-exemption-labeler@main with: github-token: ${{ secrets.PROJEN_GITHUB_TOKEN }} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/http/integ.stepfunctions.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/http/integ.stepfunctions.js.snapshot/cdk.out new file mode 100644 index 0000000000000..1f0068d32659a --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/http/integ.stepfunctions.js.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"36.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/http/integ.stepfunctions.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/http/integ.stepfunctions.js.snapshot/integ.json new file mode 100644 index 0000000000000..e16d5a28f77c1 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/http/integ.stepfunctions.js.snapshot/integ.json @@ -0,0 +1,12 @@ +{ + "version": "36.0.0", + "testCases": { + "stepfunctions-integration-integ-test/DefaultTest": { + "stacks": [ + "stepfunctions-integration" + ], + "assertionStack": "stepfunctions-integration-integ-test/DefaultTest/DeployAssert", + "assertionStackName": "stepfunctionsintegrationintegtestDefaultTestDeployAssert09AC4C77" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/http/integ.stepfunctions.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/http/integ.stepfunctions.js.snapshot/manifest.json new file mode 100644 index 0000000000000..9169101ee2313 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/http/integ.stepfunctions.js.snapshot/manifest.json @@ -0,0 +1,239 @@ +{ + "version": "36.0.0", + "artifacts": { + "stepfunctions-integration.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "stepfunctions-integration.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "stepfunctions-integration": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "stepfunctions-integration.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/19e42465a3a7d7c94541f96a140ab7bdb71eb54da666c1b3c1bc9f3a03c310a2.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "stepfunctions-integration.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "stepfunctions-integration.assets" + ], + "metadata": { + "/stepfunctions-integration/RouteStateMachine/Role/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "RouteStateMachineRoleF32EE107" + } + ], + "/stepfunctions-integration/RouteStateMachine/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "RouteStateMachineC11CAF3B" + } + ], + "/stepfunctions-integration/ExpressStateMachine/Role/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ExpressStateMachineRole4C3738D2" + } + ], + "/stepfunctions-integration/ExpressStateMachine/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ExpressStateMachineE90FFF22" + } + ], + "/stepfunctions-integration/Api/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ApiF70053CD" + } + ], + "/stepfunctions-integration/Api/DefaultStage/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ApiDefaultStage189A7074" + } + ], + "/stepfunctions-integration/Api/POST--default/InvokeRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ApiPOSTdefaultInvokeRole9137E4F5" + } + ], + "/stepfunctions-integration/Api/POST--default/InvokeRole/DefaultPolicy/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ApiPOSTdefaultInvokeRoleDefaultPolicy603C0AF3" + } + ], + "/stepfunctions-integration/Api/POST--default/Integration/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ApiPOSTdefaultIntegration15333EAA" + } + ], + "/stepfunctions-integration/Api/POST--default/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ApiPOSTdefault1EEA0D1D" + } + ], + "/stepfunctions-integration/Api/POST--start/InvokeRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ApiPOSTstartInvokeRoleA9D6BD6A" + } + ], + "/stepfunctions-integration/Api/POST--start/InvokeRole/DefaultPolicy/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ApiPOSTstartInvokeRoleDefaultPolicy495BCE0C" + } + ], + "/stepfunctions-integration/Api/POST--start/Integration/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ApiPOSTstartIntegration373B2B85" + } + ], + "/stepfunctions-integration/Api/POST--start/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ApiPOSTstartB39FD25E" + } + ], + "/stepfunctions-integration/Api/POST--start-sync/InvokeRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ApiPOSTstartsyncInvokeRoleC429A7AB" + } + ], + "/stepfunctions-integration/Api/POST--start-sync/InvokeRole/DefaultPolicy/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ApiPOSTstartsyncInvokeRoleDefaultPolicy244CA8B0" + } + ], + "/stepfunctions-integration/Api/POST--start-sync/Integration/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ApiPOSTstartsyncIntegrationB86BBC38" + } + ], + "/stepfunctions-integration/Api/POST--start-sync/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ApiPOSTstartsync3659F9A0" + } + ], + "/stepfunctions-integration/Api/POST--stop/InvokeRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ApiPOSTstopInvokeRoleB9DFDAA9" + } + ], + "/stepfunctions-integration/Api/POST--stop/InvokeRole/DefaultPolicy/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ApiPOSTstopInvokeRoleDefaultPolicy4B17C921" + } + ], + "/stepfunctions-integration/Api/POST--stop/Integration/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ApiPOSTstopIntegrationDA24B606" + } + ], + "/stepfunctions-integration/Api/POST--stop/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ApiPOSTstopBDBE4015" + } + ], + "/stepfunctions-integration/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/stepfunctions-integration/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "stepfunctions-integration" + }, + "stepfunctionsintegrationintegtestDefaultTestDeployAssert09AC4C77.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "stepfunctionsintegrationintegtestDefaultTestDeployAssert09AC4C77.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "stepfunctionsintegrationintegtestDefaultTestDeployAssert09AC4C77": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "stepfunctionsintegrationintegtestDefaultTestDeployAssert09AC4C77.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "stepfunctionsintegrationintegtestDefaultTestDeployAssert09AC4C77.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "stepfunctionsintegrationintegtestDefaultTestDeployAssert09AC4C77.assets" + ], + "metadata": { + "/stepfunctions-integration-integ-test/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/stepfunctions-integration-integ-test/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "stepfunctions-integration-integ-test/DefaultTest/DeployAssert" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/http/integ.stepfunctions.js.snapshot/stepfunctions-integration.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/http/integ.stepfunctions.js.snapshot/stepfunctions-integration.assets.json new file mode 100644 index 0000000000000..b778a7d47b763 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/http/integ.stepfunctions.js.snapshot/stepfunctions-integration.assets.json @@ -0,0 +1,19 @@ +{ + "version": "36.0.0", + "files": { + "19e42465a3a7d7c94541f96a140ab7bdb71eb54da666c1b3c1bc9f3a03c310a2": { + "source": { + "path": "stepfunctions-integration.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "19e42465a3a7d7c94541f96a140ab7bdb71eb54da666c1b3c1bc9f3a03c310a2.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/http/integ.stepfunctions.js.snapshot/stepfunctions-integration.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/http/integ.stepfunctions.js.snapshot/stepfunctions-integration.template.json new file mode 100644 index 0000000000000..9e1cc70fa86b0 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/http/integ.stepfunctions.js.snapshot/stepfunctions-integration.template.json @@ -0,0 +1,486 @@ +{ + "Resources": { + "RouteStateMachineRoleF32EE107": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "states.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "RouteStateMachineC11CAF3B": { + "Type": "AWS::StepFunctions::StateMachine", + "Properties": { + "DefinitionString": "{\"StartAt\":\"Pass1\",\"States\":{\"Pass1\":{\"Type\":\"Pass\",\"End\":true}}}", + "RoleArn": { + "Fn::GetAtt": [ + "RouteStateMachineRoleF32EE107", + "Arn" + ] + } + }, + "DependsOn": [ + "RouteStateMachineRoleF32EE107" + ], + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "ExpressStateMachineRole4C3738D2": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "states.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "ExpressStateMachineE90FFF22": { + "Type": "AWS::StepFunctions::StateMachine", + "Properties": { + "DefinitionString": "{\"StartAt\":\"Pass2\",\"States\":{\"Pass2\":{\"Type\":\"Pass\",\"End\":true}}}", + "RoleArn": { + "Fn::GetAtt": [ + "ExpressStateMachineRole4C3738D2", + "Arn" + ] + }, + "StateMachineType": "EXPRESS" + }, + "DependsOn": [ + "ExpressStateMachineRole4C3738D2" + ], + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "ApiF70053CD": { + "Type": "AWS::ApiGatewayV2::Api", + "Properties": { + "Name": "Api", + "ProtocolType": "HTTP" + } + }, + "ApiDefaultStage189A7074": { + "Type": "AWS::ApiGatewayV2::Stage", + "Properties": { + "ApiId": { + "Ref": "ApiF70053CD" + }, + "AutoDeploy": true, + "StageName": "$default" + } + }, + "ApiPOSTdefaultInvokeRole9137E4F5": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "apigateway.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "ApiPOSTdefaultInvokeRoleDefaultPolicy603C0AF3": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": "states:StartExecution", + "Effect": "Allow", + "Resource": { + "Ref": "RouteStateMachineC11CAF3B" + }, + "Sid": "AllowStepFunctionsExecution" + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "ApiPOSTdefaultInvokeRoleDefaultPolicy603C0AF3", + "Roles": [ + { + "Ref": "ApiPOSTdefaultInvokeRole9137E4F5" + } + ] + } + }, + "ApiPOSTdefaultIntegration15333EAA": { + "Type": "AWS::ApiGatewayV2::Integration", + "Properties": { + "ApiId": { + "Ref": "ApiF70053CD" + }, + "ConnectionType": "INTERNET", + "CredentialsArn": { + "Fn::GetAtt": [ + "ApiPOSTdefaultInvokeRole9137E4F5", + "Arn" + ] + }, + "IntegrationSubtype": "StepFunctions-StartExecution", + "IntegrationType": "AWS_PROXY", + "PayloadFormatVersion": "1.0", + "RequestParameters": { + "StateMachineArn": { + "Ref": "RouteStateMachineC11CAF3B" + } + } + } + }, + "ApiPOSTdefault1EEA0D1D": { + "Type": "AWS::ApiGatewayV2::Route", + "Properties": { + "ApiId": { + "Ref": "ApiF70053CD" + }, + "AuthorizationType": "NONE", + "RouteKey": "POST /default", + "Target": { + "Fn::Join": [ + "", + [ + "integrations/", + { + "Ref": "ApiPOSTdefaultIntegration15333EAA" + } + ] + ] + } + } + }, + "ApiPOSTstartInvokeRoleA9D6BD6A": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "apigateway.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "ApiPOSTstartInvokeRoleDefaultPolicy495BCE0C": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": "states:StartExecution", + "Effect": "Allow", + "Resource": { + "Ref": "RouteStateMachineC11CAF3B" + }, + "Sid": "AllowStepFunctionsExecution" + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "ApiPOSTstartInvokeRoleDefaultPolicy495BCE0C", + "Roles": [ + { + "Ref": "ApiPOSTstartInvokeRoleA9D6BD6A" + } + ] + } + }, + "ApiPOSTstartIntegration373B2B85": { + "Type": "AWS::ApiGatewayV2::Integration", + "Properties": { + "ApiId": { + "Ref": "ApiF70053CD" + }, + "ConnectionType": "INTERNET", + "CredentialsArn": { + "Fn::GetAtt": [ + "ApiPOSTstartInvokeRoleA9D6BD6A", + "Arn" + ] + }, + "IntegrationSubtype": "StepFunctions-StartExecution", + "IntegrationType": "AWS_PROXY", + "PayloadFormatVersion": "1.0", + "RequestParameters": { + "StateMachineArn": { + "Ref": "RouteStateMachineC11CAF3B" + } + } + } + }, + "ApiPOSTstartB39FD25E": { + "Type": "AWS::ApiGatewayV2::Route", + "Properties": { + "ApiId": { + "Ref": "ApiF70053CD" + }, + "AuthorizationType": "NONE", + "RouteKey": "POST /start", + "Target": { + "Fn::Join": [ + "", + [ + "integrations/", + { + "Ref": "ApiPOSTstartIntegration373B2B85" + } + ] + ] + } + } + }, + "ApiPOSTstartsyncInvokeRoleC429A7AB": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "apigateway.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "ApiPOSTstartsyncInvokeRoleDefaultPolicy244CA8B0": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": "states:StartSyncExecution", + "Effect": "Allow", + "Resource": { + "Ref": "ExpressStateMachineE90FFF22" + }, + "Sid": "AllowStepFunctionsExecution" + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "ApiPOSTstartsyncInvokeRoleDefaultPolicy244CA8B0", + "Roles": [ + { + "Ref": "ApiPOSTstartsyncInvokeRoleC429A7AB" + } + ] + } + }, + "ApiPOSTstartsyncIntegrationB86BBC38": { + "Type": "AWS::ApiGatewayV2::Integration", + "Properties": { + "ApiId": { + "Ref": "ApiF70053CD" + }, + "ConnectionType": "INTERNET", + "CredentialsArn": { + "Fn::GetAtt": [ + "ApiPOSTstartsyncInvokeRoleC429A7AB", + "Arn" + ] + }, + "IntegrationSubtype": "StepFunctions-StartSyncExecution", + "IntegrationType": "AWS_PROXY", + "PayloadFormatVersion": "1.0", + "RequestParameters": { + "StateMachineArn": { + "Ref": "ExpressStateMachineE90FFF22" + } + } + } + }, + "ApiPOSTstartsync3659F9A0": { + "Type": "AWS::ApiGatewayV2::Route", + "Properties": { + "ApiId": { + "Ref": "ApiF70053CD" + }, + "AuthorizationType": "NONE", + "RouteKey": "POST /start-sync", + "Target": { + "Fn::Join": [ + "", + [ + "integrations/", + { + "Ref": "ApiPOSTstartsyncIntegrationB86BBC38" + } + ] + ] + } + } + }, + "ApiPOSTstopInvokeRoleB9DFDAA9": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "apigateway.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "ApiPOSTstopInvokeRoleDefaultPolicy4B17C921": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": "states:StopExecution", + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":states:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":execution:", + { + "Fn::GetAtt": [ + "RouteStateMachineC11CAF3B", + "Name" + ] + }, + ":*" + ] + ] + }, + "Sid": "AllowStepFunctionsExecution" + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "ApiPOSTstopInvokeRoleDefaultPolicy4B17C921", + "Roles": [ + { + "Ref": "ApiPOSTstopInvokeRoleB9DFDAA9" + } + ] + } + }, + "ApiPOSTstopIntegrationDA24B606": { + "Type": "AWS::ApiGatewayV2::Integration", + "Properties": { + "ApiId": { + "Ref": "ApiF70053CD" + }, + "ConnectionType": "INTERNET", + "CredentialsArn": { + "Fn::GetAtt": [ + "ApiPOSTstopInvokeRoleB9DFDAA9", + "Arn" + ] + }, + "IntegrationSubtype": "StepFunctions-StopExecution", + "IntegrationType": "AWS_PROXY", + "PayloadFormatVersion": "1.0", + "RequestParameters": { + "ExecutionArn": "$request.querystring.executionArn" + } + } + }, + "ApiPOSTstopBDBE4015": { + "Type": "AWS::ApiGatewayV2::Route", + "Properties": { + "ApiId": { + "Ref": "ApiF70053CD" + }, + "AuthorizationType": "NONE", + "RouteKey": "POST /stop", + "Target": { + "Fn::Join": [ + "", + [ + "integrations/", + { + "Ref": "ApiPOSTstopIntegrationDA24B606" + } + ] + ] + } + } + } + }, + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/http/integ.stepfunctions.js.snapshot/stepfunctionsintegrationintegtestDefaultTestDeployAssert09AC4C77.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/http/integ.stepfunctions.js.snapshot/stepfunctionsintegrationintegtestDefaultTestDeployAssert09AC4C77.assets.json new file mode 100644 index 0000000000000..002ef777e5465 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/http/integ.stepfunctions.js.snapshot/stepfunctionsintegrationintegtestDefaultTestDeployAssert09AC4C77.assets.json @@ -0,0 +1,19 @@ +{ + "version": "36.0.0", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "source": { + "path": "stepfunctionsintegrationintegtestDefaultTestDeployAssert09AC4C77.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/http/integ.stepfunctions.js.snapshot/stepfunctionsintegrationintegtestDefaultTestDeployAssert09AC4C77.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/http/integ.stepfunctions.js.snapshot/stepfunctionsintegrationintegtestDefaultTestDeployAssert09AC4C77.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/http/integ.stepfunctions.js.snapshot/stepfunctionsintegrationintegtestDefaultTestDeployAssert09AC4C77.template.json @@ -0,0 +1,36 @@ +{ + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/http/integ.stepfunctions.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/http/integ.stepfunctions.js.snapshot/tree.json new file mode 100644 index 0000000000000..c8ede561fccac --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/http/integ.stepfunctions.js.snapshot/tree.json @@ -0,0 +1,999 @@ +{ + "version": "tree-0.1", + "tree": { + "id": "App", + "path": "", + "children": { + "stepfunctions-integration": { + "id": "stepfunctions-integration", + "path": "stepfunctions-integration", + "children": { + "Pass1": { + "id": "Pass1", + "path": "stepfunctions-integration/Pass1", + "constructInfo": { + "fqn": "aws-cdk-lib.aws_stepfunctions.Pass", + "version": "0.0.0" + } + }, + "RouteStateMachine": { + "id": "RouteStateMachine", + "path": "stepfunctions-integration/RouteStateMachine", + "children": { + "Role": { + "id": "Role", + "path": "stepfunctions-integration/RouteStateMachine/Role", + "children": { + "ImportRole": { + "id": "ImportRole", + "path": "stepfunctions-integration/RouteStateMachine/Role/ImportRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "stepfunctions-integration/RouteStateMachine/Role/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "states.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnRole", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Role", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "stepfunctions-integration/RouteStateMachine/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::StepFunctions::StateMachine", + "aws:cdk:cloudformation:props": { + "definitionString": "{\"StartAt\":\"Pass1\",\"States\":{\"Pass1\":{\"Type\":\"Pass\",\"End\":true}}}", + "roleArn": { + "Fn::GetAtt": [ + "RouteStateMachineRoleF32EE107", + "Arn" + ] + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_stepfunctions.CfnStateMachine", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_stepfunctions.StateMachine", + "version": "0.0.0" + } + }, + "Pass2": { + "id": "Pass2", + "path": "stepfunctions-integration/Pass2", + "constructInfo": { + "fqn": "aws-cdk-lib.aws_stepfunctions.Pass", + "version": "0.0.0" + } + }, + "ExpressStateMachine": { + "id": "ExpressStateMachine", + "path": "stepfunctions-integration/ExpressStateMachine", + "children": { + "Role": { + "id": "Role", + "path": "stepfunctions-integration/ExpressStateMachine/Role", + "children": { + "ImportRole": { + "id": "ImportRole", + "path": "stepfunctions-integration/ExpressStateMachine/Role/ImportRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "stepfunctions-integration/ExpressStateMachine/Role/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "states.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnRole", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Role", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "stepfunctions-integration/ExpressStateMachine/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::StepFunctions::StateMachine", + "aws:cdk:cloudformation:props": { + "definitionString": "{\"StartAt\":\"Pass2\",\"States\":{\"Pass2\":{\"Type\":\"Pass\",\"End\":true}}}", + "roleArn": { + "Fn::GetAtt": [ + "ExpressStateMachineRole4C3738D2", + "Arn" + ] + }, + "stateMachineType": "EXPRESS" + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_stepfunctions.CfnStateMachine", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_stepfunctions.StateMachine", + "version": "0.0.0" + } + }, + "Api": { + "id": "Api", + "path": "stepfunctions-integration/Api", + "children": { + "Resource": { + "id": "Resource", + "path": "stepfunctions-integration/Api/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ApiGatewayV2::Api", + "aws:cdk:cloudformation:props": { + "name": "Api", + "protocolType": "HTTP" + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_apigatewayv2.CfnApi", + "version": "0.0.0" + } + }, + "DefaultStage": { + "id": "DefaultStage", + "path": "stepfunctions-integration/Api/DefaultStage", + "children": { + "Resource": { + "id": "Resource", + "path": "stepfunctions-integration/Api/DefaultStage/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ApiGatewayV2::Stage", + "aws:cdk:cloudformation:props": { + "apiId": { + "Ref": "ApiF70053CD" + }, + "autoDeploy": true, + "stageName": "$default" + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_apigatewayv2.CfnStage", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_apigatewayv2.HttpStage", + "version": "0.0.0" + } + }, + "POST--default": { + "id": "POST--default", + "path": "stepfunctions-integration/Api/POST--default", + "children": { + "InvokeRole": { + "id": "InvokeRole", + "path": "stepfunctions-integration/Api/POST--default/InvokeRole", + "children": { + "ImportInvokeRole": { + "id": "ImportInvokeRole", + "path": "stepfunctions-integration/Api/POST--default/InvokeRole/ImportInvokeRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "stepfunctions-integration/Api/POST--default/InvokeRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "apigateway.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnRole", + "version": "0.0.0" + } + }, + "DefaultPolicy": { + "id": "DefaultPolicy", + "path": "stepfunctions-integration/Api/POST--default/InvokeRole/DefaultPolicy", + "children": { + "Resource": { + "id": "Resource", + "path": "stepfunctions-integration/Api/POST--default/InvokeRole/DefaultPolicy/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Policy", + "aws:cdk:cloudformation:props": { + "policyDocument": { + "Statement": [ + { + "Action": "states:StartExecution", + "Effect": "Allow", + "Resource": { + "Ref": "RouteStateMachineC11CAF3B" + }, + "Sid": "AllowStepFunctionsExecution" + } + ], + "Version": "2012-10-17" + }, + "policyName": "ApiPOSTdefaultInvokeRoleDefaultPolicy603C0AF3", + "roles": [ + { + "Ref": "ApiPOSTdefaultInvokeRole9137E4F5" + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Policy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Role", + "version": "0.0.0" + } + }, + "Integration": { + "id": "Integration", + "path": "stepfunctions-integration/Api/POST--default/Integration", + "children": { + "Resource": { + "id": "Resource", + "path": "stepfunctions-integration/Api/POST--default/Integration/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ApiGatewayV2::Integration", + "aws:cdk:cloudformation:props": { + "apiId": { + "Ref": "ApiF70053CD" + }, + "connectionType": "INTERNET", + "credentialsArn": { + "Fn::GetAtt": [ + "ApiPOSTdefaultInvokeRole9137E4F5", + "Arn" + ] + }, + "integrationSubtype": "StepFunctions-StartExecution", + "integrationType": "AWS_PROXY", + "payloadFormatVersion": "1.0", + "requestParameters": { + "StateMachineArn": { + "Ref": "RouteStateMachineC11CAF3B" + } + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_apigatewayv2.CfnIntegration", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_apigatewayv2.HttpIntegration", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "stepfunctions-integration/Api/POST--default/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ApiGatewayV2::Route", + "aws:cdk:cloudformation:props": { + "apiId": { + "Ref": "ApiF70053CD" + }, + "authorizationType": "NONE", + "routeKey": "POST /default", + "target": { + "Fn::Join": [ + "", + [ + "integrations/", + { + "Ref": "ApiPOSTdefaultIntegration15333EAA" + } + ] + ] + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_apigatewayv2.CfnRoute", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_apigatewayv2.HttpRoute", + "version": "0.0.0" + } + }, + "POST--start": { + "id": "POST--start", + "path": "stepfunctions-integration/Api/POST--start", + "children": { + "InvokeRole": { + "id": "InvokeRole", + "path": "stepfunctions-integration/Api/POST--start/InvokeRole", + "children": { + "ImportInvokeRole": { + "id": "ImportInvokeRole", + "path": "stepfunctions-integration/Api/POST--start/InvokeRole/ImportInvokeRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "stepfunctions-integration/Api/POST--start/InvokeRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "apigateway.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnRole", + "version": "0.0.0" + } + }, + "DefaultPolicy": { + "id": "DefaultPolicy", + "path": "stepfunctions-integration/Api/POST--start/InvokeRole/DefaultPolicy", + "children": { + "Resource": { + "id": "Resource", + "path": "stepfunctions-integration/Api/POST--start/InvokeRole/DefaultPolicy/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Policy", + "aws:cdk:cloudformation:props": { + "policyDocument": { + "Statement": [ + { + "Action": "states:StartExecution", + "Effect": "Allow", + "Resource": { + "Ref": "RouteStateMachineC11CAF3B" + }, + "Sid": "AllowStepFunctionsExecution" + } + ], + "Version": "2012-10-17" + }, + "policyName": "ApiPOSTstartInvokeRoleDefaultPolicy495BCE0C", + "roles": [ + { + "Ref": "ApiPOSTstartInvokeRoleA9D6BD6A" + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Policy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Role", + "version": "0.0.0" + } + }, + "Integration": { + "id": "Integration", + "path": "stepfunctions-integration/Api/POST--start/Integration", + "children": { + "Resource": { + "id": "Resource", + "path": "stepfunctions-integration/Api/POST--start/Integration/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ApiGatewayV2::Integration", + "aws:cdk:cloudformation:props": { + "apiId": { + "Ref": "ApiF70053CD" + }, + "connectionType": "INTERNET", + "credentialsArn": { + "Fn::GetAtt": [ + "ApiPOSTstartInvokeRoleA9D6BD6A", + "Arn" + ] + }, + "integrationSubtype": "StepFunctions-StartExecution", + "integrationType": "AWS_PROXY", + "payloadFormatVersion": "1.0", + "requestParameters": { + "StateMachineArn": { + "Ref": "RouteStateMachineC11CAF3B" + } + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_apigatewayv2.CfnIntegration", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_apigatewayv2.HttpIntegration", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "stepfunctions-integration/Api/POST--start/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ApiGatewayV2::Route", + "aws:cdk:cloudformation:props": { + "apiId": { + "Ref": "ApiF70053CD" + }, + "authorizationType": "NONE", + "routeKey": "POST /start", + "target": { + "Fn::Join": [ + "", + [ + "integrations/", + { + "Ref": "ApiPOSTstartIntegration373B2B85" + } + ] + ] + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_apigatewayv2.CfnRoute", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_apigatewayv2.HttpRoute", + "version": "0.0.0" + } + }, + "POST--start-sync": { + "id": "POST--start-sync", + "path": "stepfunctions-integration/Api/POST--start-sync", + "children": { + "InvokeRole": { + "id": "InvokeRole", + "path": "stepfunctions-integration/Api/POST--start-sync/InvokeRole", + "children": { + "ImportInvokeRole": { + "id": "ImportInvokeRole", + "path": "stepfunctions-integration/Api/POST--start-sync/InvokeRole/ImportInvokeRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "stepfunctions-integration/Api/POST--start-sync/InvokeRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "apigateway.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnRole", + "version": "0.0.0" + } + }, + "DefaultPolicy": { + "id": "DefaultPolicy", + "path": "stepfunctions-integration/Api/POST--start-sync/InvokeRole/DefaultPolicy", + "children": { + "Resource": { + "id": "Resource", + "path": "stepfunctions-integration/Api/POST--start-sync/InvokeRole/DefaultPolicy/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Policy", + "aws:cdk:cloudformation:props": { + "policyDocument": { + "Statement": [ + { + "Action": "states:StartSyncExecution", + "Effect": "Allow", + "Resource": { + "Ref": "ExpressStateMachineE90FFF22" + }, + "Sid": "AllowStepFunctionsExecution" + } + ], + "Version": "2012-10-17" + }, + "policyName": "ApiPOSTstartsyncInvokeRoleDefaultPolicy244CA8B0", + "roles": [ + { + "Ref": "ApiPOSTstartsyncInvokeRoleC429A7AB" + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Policy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Role", + "version": "0.0.0" + } + }, + "Integration": { + "id": "Integration", + "path": "stepfunctions-integration/Api/POST--start-sync/Integration", + "children": { + "Resource": { + "id": "Resource", + "path": "stepfunctions-integration/Api/POST--start-sync/Integration/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ApiGatewayV2::Integration", + "aws:cdk:cloudformation:props": { + "apiId": { + "Ref": "ApiF70053CD" + }, + "connectionType": "INTERNET", + "credentialsArn": { + "Fn::GetAtt": [ + "ApiPOSTstartsyncInvokeRoleC429A7AB", + "Arn" + ] + }, + "integrationSubtype": "StepFunctions-StartSyncExecution", + "integrationType": "AWS_PROXY", + "payloadFormatVersion": "1.0", + "requestParameters": { + "StateMachineArn": { + "Ref": "ExpressStateMachineE90FFF22" + } + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_apigatewayv2.CfnIntegration", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_apigatewayv2.HttpIntegration", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "stepfunctions-integration/Api/POST--start-sync/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ApiGatewayV2::Route", + "aws:cdk:cloudformation:props": { + "apiId": { + "Ref": "ApiF70053CD" + }, + "authorizationType": "NONE", + "routeKey": "POST /start-sync", + "target": { + "Fn::Join": [ + "", + [ + "integrations/", + { + "Ref": "ApiPOSTstartsyncIntegrationB86BBC38" + } + ] + ] + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_apigatewayv2.CfnRoute", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_apigatewayv2.HttpRoute", + "version": "0.0.0" + } + }, + "POST--stop": { + "id": "POST--stop", + "path": "stepfunctions-integration/Api/POST--stop", + "children": { + "InvokeRole": { + "id": "InvokeRole", + "path": "stepfunctions-integration/Api/POST--stop/InvokeRole", + "children": { + "ImportInvokeRole": { + "id": "ImportInvokeRole", + "path": "stepfunctions-integration/Api/POST--stop/InvokeRole/ImportInvokeRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "stepfunctions-integration/Api/POST--stop/InvokeRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "apigateway.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnRole", + "version": "0.0.0" + } + }, + "DefaultPolicy": { + "id": "DefaultPolicy", + "path": "stepfunctions-integration/Api/POST--stop/InvokeRole/DefaultPolicy", + "children": { + "Resource": { + "id": "Resource", + "path": "stepfunctions-integration/Api/POST--stop/InvokeRole/DefaultPolicy/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Policy", + "aws:cdk:cloudformation:props": { + "policyDocument": { + "Statement": [ + { + "Action": "states:StopExecution", + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":states:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":execution:", + { + "Fn::GetAtt": [ + "RouteStateMachineC11CAF3B", + "Name" + ] + }, + ":*" + ] + ] + }, + "Sid": "AllowStepFunctionsExecution" + } + ], + "Version": "2012-10-17" + }, + "policyName": "ApiPOSTstopInvokeRoleDefaultPolicy4B17C921", + "roles": [ + { + "Ref": "ApiPOSTstopInvokeRoleB9DFDAA9" + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Policy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Role", + "version": "0.0.0" + } + }, + "Integration": { + "id": "Integration", + "path": "stepfunctions-integration/Api/POST--stop/Integration", + "children": { + "Resource": { + "id": "Resource", + "path": "stepfunctions-integration/Api/POST--stop/Integration/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ApiGatewayV2::Integration", + "aws:cdk:cloudformation:props": { + "apiId": { + "Ref": "ApiF70053CD" + }, + "connectionType": "INTERNET", + "credentialsArn": { + "Fn::GetAtt": [ + "ApiPOSTstopInvokeRoleB9DFDAA9", + "Arn" + ] + }, + "integrationSubtype": "StepFunctions-StopExecution", + "integrationType": "AWS_PROXY", + "payloadFormatVersion": "1.0", + "requestParameters": { + "ExecutionArn": "$request.querystring.executionArn" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_apigatewayv2.CfnIntegration", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_apigatewayv2.HttpIntegration", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "stepfunctions-integration/Api/POST--stop/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ApiGatewayV2::Route", + "aws:cdk:cloudformation:props": { + "apiId": { + "Ref": "ApiF70053CD" + }, + "authorizationType": "NONE", + "routeKey": "POST /stop", + "target": { + "Fn::Join": [ + "", + [ + "integrations/", + { + "Ref": "ApiPOSTstopIntegrationDA24B606" + } + ] + ] + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_apigatewayv2.CfnRoute", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_apigatewayv2.HttpRoute", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_apigatewayv2.HttpApi", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "stepfunctions-integration/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "stepfunctions-integration/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + }, + "stepfunctions-integration-integ-test": { + "id": "stepfunctions-integration-integ-test", + "path": "stepfunctions-integration-integ-test", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "stepfunctions-integration-integ-test/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "stepfunctions-integration-integ-test/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "stepfunctions-integration-integ-test/DefaultTest/DeployAssert", + "children": { + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "stepfunctions-integration-integ-test/DefaultTest/DeployAssert/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "stepfunctions-integration-integ-test/DefaultTest/DeployAssert/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTestCase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTest", + "version": "0.0.0" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.App", + "version": "0.0.0" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/http/integ.stepfunctions.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/http/integ.stepfunctions.ts new file mode 100644 index 0000000000000..b2a816a21639b --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-apigatewayv2-integrations/test/http/integ.stepfunctions.ts @@ -0,0 +1,56 @@ +import { HttpApi, HttpIntegrationSubtype, HttpMethod, ParameterMapping } from 'aws-cdk-lib/aws-apigatewayv2'; +import * as sfn from 'aws-cdk-lib/aws-stepfunctions'; +import { App, Stack } from 'aws-cdk-lib'; +import { HttpStepFunctionsIntegration } from 'aws-cdk-lib/aws-apigatewayv2-integrations'; +import * as integ from '@aws-cdk/integ-tests-alpha'; + +const app = new App(); +const stack = new Stack(app, 'stepfunctions-integration'); + +const stateMachine = new sfn.StateMachine(stack, 'RouteStateMachine', { + definition: new sfn.Pass(stack, 'Pass1'), +}); +const expressStateMachine = new sfn.StateMachine(stack, 'ExpressStateMachine', { + definition: new sfn.Pass(stack, 'Pass2'), + stateMachineType: sfn.StateMachineType.EXPRESS, +}); + +const httpApi = new HttpApi(stack, 'Api'); +httpApi.addRoutes({ + path: '/default', + methods: [HttpMethod.POST], + integration: new HttpStepFunctionsIntegration('Integration', { + stateMachine, + }), +}); +httpApi.addRoutes({ + path: '/start', + methods: [HttpMethod.POST], + integration: new HttpStepFunctionsIntegration('Integration', { + stateMachine, + subtype: HttpIntegrationSubtype.STEPFUNCTIONS_START_EXECUTION, + }), +}); +httpApi.addRoutes({ + path: '/start-sync', + methods: [HttpMethod.POST], + integration: new HttpStepFunctionsIntegration('Integration', { + stateMachine: expressStateMachine, + subtype: HttpIntegrationSubtype.STEPFUNCTIONS_START_SYNC_EXECUTION, + }), +}); +httpApi.addRoutes({ + path: '/stop', + methods: [HttpMethod.POST], + integration: new HttpStepFunctionsIntegration('Integration', { + stateMachine, + subtype: HttpIntegrationSubtype.STEPFUNCTIONS_STOP_EXECUTION, + parameterMapping: new ParameterMapping() + .custom('ExecutionArn', '$request.querystring.executionArn'), + }), +}); + +new integ.IntegTest(app, 'stepfunctions-integration-integ-test', { + testCases: [stack], +}); +app.synth(); \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-grant-imported-api.js.snapshot/GraphqlGrantImportedApiIntegDefaultTestDeployAssertE072C285.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-grant-imported-api.js.snapshot/GraphqlGrantImportedApiIntegDefaultTestDeployAssertE072C285.assets.json new file mode 100644 index 0000000000000..132fc9ca01136 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-grant-imported-api.js.snapshot/GraphqlGrantImportedApiIntegDefaultTestDeployAssertE072C285.assets.json @@ -0,0 +1,19 @@ +{ + "version": "36.0.0", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "source": { + "path": "GraphqlGrantImportedApiIntegDefaultTestDeployAssertE072C285.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-grant-imported-api.js.snapshot/GraphqlGrantImportedApiIntegDefaultTestDeployAssertE072C285.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-grant-imported-api.js.snapshot/GraphqlGrantImportedApiIntegDefaultTestDeployAssertE072C285.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-grant-imported-api.js.snapshot/GraphqlGrantImportedApiIntegDefaultTestDeployAssertE072C285.template.json @@ -0,0 +1,36 @@ +{ + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-grant-imported-api.js.snapshot/aws-appsync-integ.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-grant-imported-api.js.snapshot/aws-appsync-integ.assets.json new file mode 100644 index 0000000000000..c4ce0ba3b127b --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-grant-imported-api.js.snapshot/aws-appsync-integ.assets.json @@ -0,0 +1,19 @@ +{ + "version": "36.0.0", + "files": { + "eaa071d73fbf78d2b0887200d22f7bab11fc3b13290fd6d6d13fde6b1036c165": { + "source": { + "path": "aws-appsync-integ.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "eaa071d73fbf78d2b0887200d22f7bab11fc3b13290fd6d6d13fde6b1036c165.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-grant-imported-api.js.snapshot/aws-appsync-integ.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-grant-imported-api.js.snapshot/aws-appsync-integ.template.json new file mode 100644 index 0000000000000..ba09319e244a3 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-grant-imported-api.js.snapshot/aws-appsync-integ.template.json @@ -0,0 +1,116 @@ +{ + "Resources": { + "PoolD3F588B8": { + "Type": "AWS::Cognito::UserPool", + "Properties": { + "AccountRecoverySetting": { + "RecoveryMechanisms": [ + { + "Name": "verified_phone_number", + "Priority": 1 + }, + { + "Name": "verified_email", + "Priority": 2 + } + ] + }, + "AdminCreateUserConfig": { + "AllowAdminCreateUserOnly": true + }, + "EmailVerificationMessage": "The verification code to your new account is {####}", + "EmailVerificationSubject": "Verify your new account", + "SmsVerificationMessage": "The verification code to your new account is {####}", + "UserPoolName": "myPool", + "VerificationMessageTemplate": { + "DefaultEmailOption": "CONFIRM_WITH_CODE", + "EmailMessage": "The verification code to your new account is {####}", + "EmailSubject": "Verify your new account", + "SmsMessage": "The verification code to your new account is {####}" + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "ApiF70053CD": { + "Type": "AWS::AppSync::GraphQLApi", + "Properties": { + "AdditionalAuthenticationProviders": [ + { + "AuthenticationType": "AWS_IAM" + } + ], + "AuthenticationType": "AMAZON_COGNITO_USER_POOLS", + "Name": "Integ_Test_IAM", + "UserPoolConfig": { + "AwsRegion": { + "Ref": "AWS::Region" + }, + "DefaultAction": "ALLOW", + "UserPoolId": { + "Ref": "PoolD3F588B8" + } + } + } + }, + "ApiSchema510EECD7": { + "Type": "AWS::AppSync::GraphQLSchema", + "Properties": { + "ApiId": { + "Fn::GetAtt": [ + "ApiF70053CD", + "ApiId" + ] + }, + "Definition": "type test @aws_iam {\n id: String!\n version: String!\n}\n\ntype Query {\n getTest(id: String!): test\n getTests: [ test! ]\n @aws_iam \n}\n\ninput TestInput {\n version: String!\n}\n\ntype Mutation {\n addTest(input: TestInput!): test\n @aws_iam\n}\n" + } + } + }, + "Outputs": { + "ExportsOutputFnGetAttApiF70053CDApiIdF185726B": { + "Value": { + "Fn::GetAtt": [ + "ApiF70053CD", + "ApiId" + ] + }, + "Export": { + "Name": "aws-appsync-integ:ExportsOutputFnGetAttApiF70053CDApiIdF185726B" + } + } + }, + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-grant-imported-api.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-grant-imported-api.js.snapshot/cdk.out new file mode 100644 index 0000000000000..1f0068d32659a --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-grant-imported-api.js.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"36.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-grant-imported-api.js.snapshot/imported-stack.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-grant-imported-api.js.snapshot/imported-stack.assets.json new file mode 100644 index 0000000000000..5dc8598e31d89 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-grant-imported-api.js.snapshot/imported-stack.assets.json @@ -0,0 +1,19 @@ +{ + "version": "36.0.0", + "files": { + "33fc02df19070d9366b8e00d2471256ee84cacf09985e1a83461f75872733e2e": { + "source": { + "path": "imported-stack.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "33fc02df19070d9366b8e00d2471256ee84cacf09985e1a83461f75872733e2e.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-grant-imported-api.js.snapshot/imported-stack.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-grant-imported-api.js.snapshot/imported-stack.template.json new file mode 100644 index 0000000000000..103c197099d13 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-grant-imported-api.js.snapshot/imported-stack.template.json @@ -0,0 +1,282 @@ +{ + "Resources": { + "lambdaRoleC844FDB1": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "lambdaRoleDefaultPolicyA63A8A92": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": "appsync:GraphQL", + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":appsync:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":apis/", + { + "Fn::ImportValue": "aws-appsync-integ:ExportsOutputFnGetAttApiF70053CDApiIdF185726B" + }, + "/types/Query/fields/getPost" + ] + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "lambdaRoleDefaultPolicyA63A8A92", + "Roles": [ + { + "Ref": "lambdaRoleC844FDB1" + } + ] + } + }, + "mutatioLambdaRole7F96C419": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "mutatioLambdaRoleDefaultPolicyCB07404D": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": "appsync:GraphQL", + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":appsync:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":apis/", + { + "Fn::ImportValue": "aws-appsync-integ:ExportsOutputFnGetAttApiF70053CDApiIdF185726B" + }, + "/types/Mutation/*" + ] + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "mutatioLambdaRoleDefaultPolicyCB07404D", + "Roles": [ + { + "Ref": "mutatioLambdaRole7F96C419" + } + ] + } + }, + "queryLambdaRole5A00034A": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "queryLambdaRoleDefaultPolicyC3CBAE04": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": "appsync:GraphQL", + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":appsync:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":apis/", + { + "Fn::ImportValue": "aws-appsync-integ:ExportsOutputFnGetAttApiF70053CDApiIdF185726B" + }, + "/types/Query/*" + ] + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "queryLambdaRoleDefaultPolicyC3CBAE04", + "Roles": [ + { + "Ref": "queryLambdaRole5A00034A" + } + ] + } + }, + "subscriptionLambdaRoleB3A245CA": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "subscriptionLambdaRoleDefaultPolicy11B257BC": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": "appsync:GraphQL", + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":appsync:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":apis/", + { + "Fn::ImportValue": "aws-appsync-integ:ExportsOutputFnGetAttApiF70053CDApiIdF185726B" + }, + "/types/Subscription/*" + ] + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "subscriptionLambdaRoleDefaultPolicy11B257BC", + "Roles": [ + { + "Ref": "subscriptionLambdaRoleB3A245CA" + } + ] + } + } + }, + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-grant-imported-api.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-grant-imported-api.js.snapshot/integ.json new file mode 100644 index 0000000000000..c958b67489e04 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-grant-imported-api.js.snapshot/integ.json @@ -0,0 +1,12 @@ +{ + "version": "36.0.0", + "testCases": { + "GraphqlGrantImportedApiInteg/DefaultTest": { + "stacks": [ + "imported-stack" + ], + "assertionStack": "GraphqlGrantImportedApiInteg/DefaultTest/DeployAssert", + "assertionStackName": "GraphqlGrantImportedApiIntegDefaultTestDeployAssertE072C285" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-grant-imported-api.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-grant-imported-api.js.snapshot/manifest.json new file mode 100644 index 0000000000000..05fcf1f21e63a --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-grant-imported-api.js.snapshot/manifest.json @@ -0,0 +1,228 @@ +{ + "version": "36.0.0", + "artifacts": { + "aws-appsync-integ.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "aws-appsync-integ.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "aws-appsync-integ": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "aws-appsync-integ.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/eaa071d73fbf78d2b0887200d22f7bab11fc3b13290fd6d6d13fde6b1036c165.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "aws-appsync-integ.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "aws-appsync-integ.assets" + ], + "metadata": { + "/aws-appsync-integ/Pool/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "PoolD3F588B8" + } + ], + "/aws-appsync-integ/Api/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ApiF70053CD" + } + ], + "/aws-appsync-integ/Api/Schema": [ + { + "type": "aws:cdk:logicalId", + "data": "ApiSchema510EECD7" + } + ], + "/aws-appsync-integ/Exports/Output{\"Fn::GetAtt\":[\"ApiF70053CD\",\"ApiId\"]}": [ + { + "type": "aws:cdk:logicalId", + "data": "ExportsOutputFnGetAttApiF70053CDApiIdF185726B" + } + ], + "/aws-appsync-integ/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/aws-appsync-integ/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "aws-appsync-integ" + }, + "imported-stack.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "imported-stack.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "imported-stack": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "imported-stack.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/33fc02df19070d9366b8e00d2471256ee84cacf09985e1a83461f75872733e2e.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "imported-stack.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "aws-appsync-integ", + "imported-stack.assets" + ], + "metadata": { + "/imported-stack/lambdaRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "lambdaRoleC844FDB1" + } + ], + "/imported-stack/lambdaRole/DefaultPolicy/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "lambdaRoleDefaultPolicyA63A8A92" + } + ], + "/imported-stack/mutatioLambdaRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "mutatioLambdaRole7F96C419" + } + ], + "/imported-stack/mutatioLambdaRole/DefaultPolicy/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "mutatioLambdaRoleDefaultPolicyCB07404D" + } + ], + "/imported-stack/queryLambdaRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "queryLambdaRole5A00034A" + } + ], + "/imported-stack/queryLambdaRole/DefaultPolicy/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "queryLambdaRoleDefaultPolicyC3CBAE04" + } + ], + "/imported-stack/subscriptionLambdaRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "subscriptionLambdaRoleB3A245CA" + } + ], + "/imported-stack/subscriptionLambdaRole/DefaultPolicy/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "subscriptionLambdaRoleDefaultPolicy11B257BC" + } + ], + "/imported-stack/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/imported-stack/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "imported-stack" + }, + "GraphqlGrantImportedApiIntegDefaultTestDeployAssertE072C285.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "GraphqlGrantImportedApiIntegDefaultTestDeployAssertE072C285.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "GraphqlGrantImportedApiIntegDefaultTestDeployAssertE072C285": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "GraphqlGrantImportedApiIntegDefaultTestDeployAssertE072C285.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "GraphqlGrantImportedApiIntegDefaultTestDeployAssertE072C285.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "GraphqlGrantImportedApiIntegDefaultTestDeployAssertE072C285.assets" + ], + "metadata": { + "/GraphqlGrantImportedApiInteg/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/GraphqlGrantImportedApiInteg/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "GraphqlGrantImportedApiInteg/DefaultTest/DeployAssert" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-grant-imported-api.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-grant-imported-api.js.snapshot/tree.json new file mode 100644 index 0000000000000..fc4f63f478dc1 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-grant-imported-api.js.snapshot/tree.json @@ -0,0 +1,688 @@ +{ + "version": "tree-0.1", + "tree": { + "id": "App", + "path": "", + "children": { + "aws-appsync-integ": { + "id": "aws-appsync-integ", + "path": "aws-appsync-integ", + "children": { + "Pool": { + "id": "Pool", + "path": "aws-appsync-integ/Pool", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-appsync-integ/Pool/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Cognito::UserPool", + "aws:cdk:cloudformation:props": { + "accountRecoverySetting": { + "recoveryMechanisms": [ + { + "name": "verified_phone_number", + "priority": 1 + }, + { + "name": "verified_email", + "priority": 2 + } + ] + }, + "adminCreateUserConfig": { + "allowAdminCreateUserOnly": true + }, + "emailVerificationMessage": "The verification code to your new account is {####}", + "emailVerificationSubject": "Verify your new account", + "smsVerificationMessage": "The verification code to your new account is {####}", + "userPoolName": "myPool", + "verificationMessageTemplate": { + "defaultEmailOption": "CONFIRM_WITH_CODE", + "emailMessage": "The verification code to your new account is {####}", + "emailSubject": "Verify your new account", + "smsMessage": "The verification code to your new account is {####}" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_cognito.CfnUserPool", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_cognito.UserPool", + "version": "0.0.0" + } + }, + "Api": { + "id": "Api", + "path": "aws-appsync-integ/Api", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-appsync-integ/Api/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::AppSync::GraphQLApi", + "aws:cdk:cloudformation:props": { + "additionalAuthenticationProviders": [ + { + "authenticationType": "AWS_IAM" + } + ], + "authenticationType": "AMAZON_COGNITO_USER_POOLS", + "name": "Integ_Test_IAM", + "userPoolConfig": { + "userPoolId": { + "Ref": "PoolD3F588B8" + }, + "awsRegion": { + "Ref": "AWS::Region" + }, + "defaultAction": "ALLOW" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_appsync.CfnGraphQLApi", + "version": "0.0.0" + } + }, + "Schema": { + "id": "Schema", + "path": "aws-appsync-integ/Api/Schema", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::AppSync::GraphQLSchema", + "aws:cdk:cloudformation:props": { + "apiId": { + "Fn::GetAtt": [ + "ApiF70053CD", + "ApiId" + ] + }, + "definition": "type test @aws_iam {\n id: String!\n version: String!\n}\n\ntype Query {\n getTest(id: String!): test\n getTests: [ test! ]\n @aws_iam \n}\n\ninput TestInput {\n version: String!\n}\n\ntype Mutation {\n addTest(input: TestInput!): test\n @aws_iam\n}\n" + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_appsync.CfnGraphQLSchema", + "version": "0.0.0" + } + }, + "LogGroup": { + "id": "LogGroup", + "path": "aws-appsync-integ/Api/LogGroup", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_appsync.GraphqlApi", + "version": "0.0.0" + } + }, + "ImportedApi": { + "id": "ImportedApi", + "path": "aws-appsync-integ/ImportedApi", + "constructInfo": { + "fqn": "aws-cdk-lib.aws_appsync.GraphqlApiBase", + "version": "0.0.0" + } + }, + "Exports": { + "id": "Exports", + "path": "aws-appsync-integ/Exports", + "children": { + "Output{\"Fn::GetAtt\":[\"ApiF70053CD\",\"ApiId\"]}": { + "id": "Output{\"Fn::GetAtt\":[\"ApiF70053CD\",\"ApiId\"]}", + "path": "aws-appsync-integ/Exports/Output{\"Fn::GetAtt\":[\"ApiF70053CD\",\"ApiId\"]}", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnOutput", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "aws-appsync-integ/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "aws-appsync-integ/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + }, + "imported-stack": { + "id": "imported-stack", + "path": "imported-stack", + "children": { + "lambdaRole": { + "id": "lambdaRole", + "path": "imported-stack/lambdaRole", + "children": { + "ImportlambdaRole": { + "id": "ImportlambdaRole", + "path": "imported-stack/lambdaRole/ImportlambdaRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "imported-stack/lambdaRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnRole", + "version": "0.0.0" + } + }, + "DefaultPolicy": { + "id": "DefaultPolicy", + "path": "imported-stack/lambdaRole/DefaultPolicy", + "children": { + "Resource": { + "id": "Resource", + "path": "imported-stack/lambdaRole/DefaultPolicy/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Policy", + "aws:cdk:cloudformation:props": { + "policyDocument": { + "Statement": [ + { + "Action": "appsync:GraphQL", + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":appsync:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":apis/", + { + "Fn::ImportValue": "aws-appsync-integ:ExportsOutputFnGetAttApiF70053CDApiIdF185726B" + }, + "/types/Query/fields/getPost" + ] + ] + } + } + ], + "Version": "2012-10-17" + }, + "policyName": "lambdaRoleDefaultPolicyA63A8A92", + "roles": [ + { + "Ref": "lambdaRoleC844FDB1" + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Policy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Role", + "version": "0.0.0" + } + }, + "mutatioLambdaRole": { + "id": "mutatioLambdaRole", + "path": "imported-stack/mutatioLambdaRole", + "children": { + "ImportmutatioLambdaRole": { + "id": "ImportmutatioLambdaRole", + "path": "imported-stack/mutatioLambdaRole/ImportmutatioLambdaRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "imported-stack/mutatioLambdaRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnRole", + "version": "0.0.0" + } + }, + "DefaultPolicy": { + "id": "DefaultPolicy", + "path": "imported-stack/mutatioLambdaRole/DefaultPolicy", + "children": { + "Resource": { + "id": "Resource", + "path": "imported-stack/mutatioLambdaRole/DefaultPolicy/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Policy", + "aws:cdk:cloudformation:props": { + "policyDocument": { + "Statement": [ + { + "Action": "appsync:GraphQL", + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":appsync:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":apis/", + { + "Fn::ImportValue": "aws-appsync-integ:ExportsOutputFnGetAttApiF70053CDApiIdF185726B" + }, + "/types/Mutation/*" + ] + ] + } + } + ], + "Version": "2012-10-17" + }, + "policyName": "mutatioLambdaRoleDefaultPolicyCB07404D", + "roles": [ + { + "Ref": "mutatioLambdaRole7F96C419" + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Policy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Role", + "version": "0.0.0" + } + }, + "queryLambdaRole": { + "id": "queryLambdaRole", + "path": "imported-stack/queryLambdaRole", + "children": { + "ImportqueryLambdaRole": { + "id": "ImportqueryLambdaRole", + "path": "imported-stack/queryLambdaRole/ImportqueryLambdaRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "imported-stack/queryLambdaRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnRole", + "version": "0.0.0" + } + }, + "DefaultPolicy": { + "id": "DefaultPolicy", + "path": "imported-stack/queryLambdaRole/DefaultPolicy", + "children": { + "Resource": { + "id": "Resource", + "path": "imported-stack/queryLambdaRole/DefaultPolicy/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Policy", + "aws:cdk:cloudformation:props": { + "policyDocument": { + "Statement": [ + { + "Action": "appsync:GraphQL", + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":appsync:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":apis/", + { + "Fn::ImportValue": "aws-appsync-integ:ExportsOutputFnGetAttApiF70053CDApiIdF185726B" + }, + "/types/Query/*" + ] + ] + } + } + ], + "Version": "2012-10-17" + }, + "policyName": "queryLambdaRoleDefaultPolicyC3CBAE04", + "roles": [ + { + "Ref": "queryLambdaRole5A00034A" + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Policy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Role", + "version": "0.0.0" + } + }, + "subscriptionLambdaRole": { + "id": "subscriptionLambdaRole", + "path": "imported-stack/subscriptionLambdaRole", + "children": { + "ImportsubscriptionLambdaRole": { + "id": "ImportsubscriptionLambdaRole", + "path": "imported-stack/subscriptionLambdaRole/ImportsubscriptionLambdaRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "imported-stack/subscriptionLambdaRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnRole", + "version": "0.0.0" + } + }, + "DefaultPolicy": { + "id": "DefaultPolicy", + "path": "imported-stack/subscriptionLambdaRole/DefaultPolicy", + "children": { + "Resource": { + "id": "Resource", + "path": "imported-stack/subscriptionLambdaRole/DefaultPolicy/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Policy", + "aws:cdk:cloudformation:props": { + "policyDocument": { + "Statement": [ + { + "Action": "appsync:GraphQL", + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":appsync:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":apis/", + { + "Fn::ImportValue": "aws-appsync-integ:ExportsOutputFnGetAttApiF70053CDApiIdF185726B" + }, + "/types/Subscription/*" + ] + ] + } + } + ], + "Version": "2012-10-17" + }, + "policyName": "subscriptionLambdaRoleDefaultPolicy11B257BC", + "roles": [ + { + "Ref": "subscriptionLambdaRoleB3A245CA" + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Policy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Role", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "imported-stack/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "imported-stack/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + }, + "GraphqlGrantImportedApiInteg": { + "id": "GraphqlGrantImportedApiInteg", + "path": "GraphqlGrantImportedApiInteg", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "GraphqlGrantImportedApiInteg/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "GraphqlGrantImportedApiInteg/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "GraphqlGrantImportedApiInteg/DefaultTest/DeployAssert", + "children": { + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "GraphqlGrantImportedApiInteg/DefaultTest/DeployAssert/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "GraphqlGrantImportedApiInteg/DefaultTest/DeployAssert/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTestCase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTest", + "version": "0.0.0" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.App", + "version": "0.0.0" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-grant-imported-api.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-grant-imported-api.ts new file mode 100644 index 0000000000000..fab8a1ce93027 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-grant-imported-api.ts @@ -0,0 +1,91 @@ +import { join } from 'path'; +import { UserPool } from 'aws-cdk-lib/aws-cognito'; +import { App, RemovalPolicy, Stack, StackProps } from 'aws-cdk-lib'; +import { + AuthorizationType, + GraphqlApi, + UserPoolDefaultAction, + SchemaFile, + IamResource, +} from 'aws-cdk-lib/aws-appsync'; +import { IntegTest } from '@aws-cdk/integ-tests-alpha'; +import { ServicePrincipal, Role } from 'aws-cdk-lib/aws-iam'; + +class OriginalStack extends Stack { + + public readonly apiId: string; + + constructor(scope: App, id: string) { + super(scope, id); + + const userPool = new UserPool(this, 'Pool', { + userPoolName: 'myPool', + removalPolicy: RemovalPolicy.DESTROY, + }); + + const api = new GraphqlApi(this, 'Api', { + name: 'Integ_Test_IAM', + schema: SchemaFile.fromAsset(join(__dirname, 'integ.graphql-iam.graphql')), + authorizationConfig: { + defaultAuthorization: { + authorizationType: AuthorizationType.USER_POOL, + userPoolConfig: { + userPool, + defaultAction: UserPoolDefaultAction.ALLOW, + }, + }, + additionalAuthorizationModes: [ + { + authorizationType: AuthorizationType.IAM, + }, + ], + }, + }); + + this.apiId = api.apiId; + } +} + +interface ImportedStackProps extends StackProps { + apiId: string; +} + +class ImportedStack extends Stack { + constructor(scope: App, id: string, props: ImportedStackProps) { + super(scope, id); + + const importedApi = GraphqlApi.fromGraphqlApiAttributes(originalStack, 'ImportedApi', { + graphqlApiId: `${props.apiId}`, + }); + + const lambdaRole = new Role(this, 'lambdaRole', { + assumedBy: new ServicePrincipal('lambda.amazonaws.com'), + }); + importedApi.grant(lambdaRole, IamResource.custom('types/Query/fields/getPost'), 'appsync:GraphQL'); + + const mutationLambdaRole = new Role(this, 'mutatioLambdaRole', { + assumedBy: new ServicePrincipal('lambda.amazonaws.com'), + }); + importedApi.grantMutation(mutationLambdaRole); + + const queryLambdaRole = new Role(this, 'queryLambdaRole', { + assumedBy: new ServicePrincipal('lambda.amazonaws.com'), + }); + importedApi.grantQuery(queryLambdaRole); + + const subscriptionLambdaRole = new Role(this, 'subscriptionLambdaRole', { + assumedBy: new ServicePrincipal('lambda.amazonaws.com'), + }); + importedApi.grantSubscription(subscriptionLambdaRole); + } +} + +const app = new App(); +const originalStack = new OriginalStack(app, 'aws-appsync-integ'); +const importedStack = new ImportedStack(app, 'imported-stack', { + apiId: originalStack.apiId, +}); + +new IntegTest(app, 'GraphqlGrantImportedApiInteg', { + testCases: [importedStack], +}); diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-autoscaling/test/integ.asg-step-scaling.js.snapshot/autoscaling-step-scaling.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-autoscaling/test/integ.asg-step-scaling.js.snapshot/autoscaling-step-scaling.assets.json index 82a1625220d4e..0e8e3a9ec8b31 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-autoscaling/test/integ.asg-step-scaling.js.snapshot/autoscaling-step-scaling.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-autoscaling/test/integ.asg-step-scaling.js.snapshot/autoscaling-step-scaling.assets.json @@ -1,7 +1,7 @@ { "version": "36.0.0", "files": { - "b6351ec1c05eef818c53fedccb18fb96ff55ee77e2049a05d2b5b15903984b19": { + "9275d003ca02cbf717d5af0130f852ba74ab89d57dbc60b2edf6737afc7f4757": { "source": { "path": "autoscaling-step-scaling.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "b6351ec1c05eef818c53fedccb18fb96ff55ee77e2049a05d2b5b15903984b19.json", + "objectKey": "9275d003ca02cbf717d5af0130f852ba74ab89d57dbc60b2edf6737afc7f4757.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-autoscaling/test/integ.asg-step-scaling.js.snapshot/autoscaling-step-scaling.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-autoscaling/test/integ.asg-step-scaling.js.snapshot/autoscaling-step-scaling.template.json index d15d364a6c214..d0a582898d7c3 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-autoscaling/test/integ.asg-step-scaling.js.snapshot/autoscaling-step-scaling.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-autoscaling/test/integ.asg-step-scaling.js.snapshot/autoscaling-step-scaling.template.json @@ -643,6 +643,99 @@ "Statistic": "Average", "Threshold": 50 } + }, + "ASGStepScalingWithDefaultAdjustmentTypeLowerPolicyA6C1EA33": { + "Type": "AWS::AutoScaling::ScalingPolicy", + "Properties": { + "AdjustmentType": "ChangeInCapacity", + "AutoScalingGroupName": { + "Ref": "ASG46ED3070" + }, + "MetricAggregationType": "Maximum", + "PolicyType": "StepScaling", + "StepAdjustments": [ + { + "MetricIntervalUpperBound": 0, + "ScalingAdjustment": -1 + } + ] + } + }, + "ASGStepScalingWithDefaultAdjustmentTypeLowerAlarmF9F52487": { + "Type": "AWS::CloudWatch::Alarm", + "Properties": { + "AlarmActions": [ + { + "Ref": "ASGStepScalingWithDefaultAdjustmentTypeLowerPolicyA6C1EA33" + } + ], + "AlarmDescription": "Lower threshold scaling alarm", + "ComparisonOperator": "LessThanOrEqualToThreshold", + "DatapointsToAlarm": 5, + "Dimensions": [ + { + "Name": "AutoScalingGroupName", + "Value": { + "Ref": "ASG46ED3070" + } + } + ], + "EvaluationPeriods": 10, + "MetricName": "DiskWriteOps", + "Namespace": "AWS/EC2", + "Period": 300, + "Statistic": "Average", + "Threshold": 100 + } + }, + "ASGStepScalingWithDefaultAdjustmentTypeUpperPolicy08CC2D99": { + "Type": "AWS::AutoScaling::ScalingPolicy", + "Properties": { + "AdjustmentType": "ChangeInCapacity", + "AutoScalingGroupName": { + "Ref": "ASG46ED3070" + }, + "MetricAggregationType": "Maximum", + "PolicyType": "StepScaling", + "StepAdjustments": [ + { + "MetricIntervalLowerBound": 0, + "MetricIntervalUpperBound": 200, + "ScalingAdjustment": 1 + }, + { + "MetricIntervalLowerBound": 200, + "ScalingAdjustment": 2 + } + ] + } + }, + "ASGStepScalingWithDefaultAdjustmentTypeUpperAlarm2379E17B": { + "Type": "AWS::CloudWatch::Alarm", + "Properties": { + "AlarmActions": [ + { + "Ref": "ASGStepScalingWithDefaultAdjustmentTypeUpperPolicy08CC2D99" + } + ], + "AlarmDescription": "Upper threshold scaling alarm", + "ComparisonOperator": "GreaterThanOrEqualToThreshold", + "DatapointsToAlarm": 5, + "Dimensions": [ + { + "Name": "AutoScalingGroupName", + "Value": { + "Ref": "ASG46ED3070" + } + } + ], + "EvaluationPeriods": 10, + "MetricName": "DiskWriteOps", + "Namespace": "AWS/EC2", + "Period": 300, + "Statistic": "Average", + "Threshold": 300 + } } }, "Parameters": { diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-autoscaling/test/integ.asg-step-scaling.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-autoscaling/test/integ.asg-step-scaling.js.snapshot/manifest.json index 877089e7ae7f2..c3907637c2628 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-autoscaling/test/integ.asg-step-scaling.js.snapshot/manifest.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-autoscaling/test/integ.asg-step-scaling.js.snapshot/manifest.json @@ -18,7 +18,7 @@ "validateOnSynth": false, "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/b6351ec1c05eef818c53fedccb18fb96ff55ee77e2049a05d2b5b15903984b19.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/9275d003ca02cbf717d5af0130f852ba74ab89d57dbc60b2edf6737afc7f4757.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -226,6 +226,30 @@ "data": "ASGStepScalingUpperAlarmD989D805" } ], + "/autoscaling-step-scaling/ASG/StepScalingWithDefaultAdjustmentType/LowerPolicy/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ASGStepScalingWithDefaultAdjustmentTypeLowerPolicyA6C1EA33" + } + ], + "/autoscaling-step-scaling/ASG/StepScalingWithDefaultAdjustmentType/LowerAlarm/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ASGStepScalingWithDefaultAdjustmentTypeLowerAlarmF9F52487" + } + ], + "/autoscaling-step-scaling/ASG/StepScalingWithDefaultAdjustmentType/UpperPolicy/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ASGStepScalingWithDefaultAdjustmentTypeUpperPolicy08CC2D99" + } + ], + "/autoscaling-step-scaling/ASG/StepScalingWithDefaultAdjustmentType/UpperAlarm/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ASGStepScalingWithDefaultAdjustmentTypeUpperAlarm2379E17B" + } + ], "/autoscaling-step-scaling/SsmParameterValue:--aws--service--ami-amazon-linux-latest--amzn2-ami-hvm-x86_64-gp2:C96584B6-F00A-464E-AD19-53AFF4B05118.Parameter": [ { "type": "aws:cdk:logicalId", diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-autoscaling/test/integ.asg-step-scaling.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-autoscaling/test/integ.asg-step-scaling.js.snapshot/tree.json index ddc20e3a7c9b3..b983ee1e8ae20 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-autoscaling/test/integ.asg-step-scaling.js.snapshot/tree.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-autoscaling/test/integ.asg-step-scaling.js.snapshot/tree.json @@ -1067,6 +1067,181 @@ "fqn": "constructs.Construct", "version": "10.3.0" } + }, + "StepScalingWithDefaultAdjustmentType": { + "id": "StepScalingWithDefaultAdjustmentType", + "path": "autoscaling-step-scaling/ASG/StepScalingWithDefaultAdjustmentType", + "children": { + "LowerPolicy": { + "id": "LowerPolicy", + "path": "autoscaling-step-scaling/ASG/StepScalingWithDefaultAdjustmentType/LowerPolicy", + "children": { + "Resource": { + "id": "Resource", + "path": "autoscaling-step-scaling/ASG/StepScalingWithDefaultAdjustmentType/LowerPolicy/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::AutoScaling::ScalingPolicy", + "aws:cdk:cloudformation:props": { + "adjustmentType": "ChangeInCapacity", + "autoScalingGroupName": { + "Ref": "ASG46ED3070" + }, + "metricAggregationType": "Maximum", + "policyType": "StepScaling", + "stepAdjustments": [ + { + "metricIntervalUpperBound": 0, + "scalingAdjustment": -1 + } + ] + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "LowerAlarm": { + "id": "LowerAlarm", + "path": "autoscaling-step-scaling/ASG/StepScalingWithDefaultAdjustmentType/LowerAlarm", + "children": { + "Resource": { + "id": "Resource", + "path": "autoscaling-step-scaling/ASG/StepScalingWithDefaultAdjustmentType/LowerAlarm/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::CloudWatch::Alarm", + "aws:cdk:cloudformation:props": { + "alarmActions": [ + { + "Ref": "ASGStepScalingWithDefaultAdjustmentTypeLowerPolicyA6C1EA33" + } + ], + "alarmDescription": "Lower threshold scaling alarm", + "comparisonOperator": "LessThanOrEqualToThreshold", + "datapointsToAlarm": 5, + "dimensions": [ + { + "name": "AutoScalingGroupName", + "value": { + "Ref": "ASG46ED3070" + } + } + ], + "evaluationPeriods": 10, + "metricName": "DiskWriteOps", + "namespace": "AWS/EC2", + "period": 300, + "statistic": "Average", + "threshold": 100 + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "UpperPolicy": { + "id": "UpperPolicy", + "path": "autoscaling-step-scaling/ASG/StepScalingWithDefaultAdjustmentType/UpperPolicy", + "children": { + "Resource": { + "id": "Resource", + "path": "autoscaling-step-scaling/ASG/StepScalingWithDefaultAdjustmentType/UpperPolicy/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::AutoScaling::ScalingPolicy", + "aws:cdk:cloudformation:props": { + "adjustmentType": "ChangeInCapacity", + "autoScalingGroupName": { + "Ref": "ASG46ED3070" + }, + "metricAggregationType": "Maximum", + "policyType": "StepScaling", + "stepAdjustments": [ + { + "metricIntervalLowerBound": 0, + "metricIntervalUpperBound": 200, + "scalingAdjustment": 1 + }, + { + "metricIntervalLowerBound": 200, + "scalingAdjustment": 2 + } + ] + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "UpperAlarm": { + "id": "UpperAlarm", + "path": "autoscaling-step-scaling/ASG/StepScalingWithDefaultAdjustmentType/UpperAlarm", + "children": { + "Resource": { + "id": "Resource", + "path": "autoscaling-step-scaling/ASG/StepScalingWithDefaultAdjustmentType/UpperAlarm/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::CloudWatch::Alarm", + "aws:cdk:cloudformation:props": { + "alarmActions": [ + { + "Ref": "ASGStepScalingWithDefaultAdjustmentTypeUpperPolicy08CC2D99" + } + ], + "alarmDescription": "Upper threshold scaling alarm", + "comparisonOperator": "GreaterThanOrEqualToThreshold", + "datapointsToAlarm": 5, + "dimensions": [ + { + "name": "AutoScalingGroupName", + "value": { + "Ref": "ASG46ED3070" + } + } + ], + "evaluationPeriods": 10, + "metricName": "DiskWriteOps", + "namespace": "AWS/EC2", + "period": 300, + "statistic": "Average", + "threshold": 300 + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } } }, "constructInfo": { diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-autoscaling/test/integ.asg-step-scaling.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-autoscaling/test/integ.asg-step-scaling.ts index c49ed5d312e98..081d85b8c6ec8 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-autoscaling/test/integ.asg-step-scaling.ts +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-autoscaling/test/integ.asg-step-scaling.ts @@ -30,6 +30,17 @@ asg.scaleOnMetric('StepScaling', { datapointsToAlarm: 5, metricAggregationType: autoscaling.MetricAggregationType.MAXIMUM, }); +asg.scaleOnMetric('StepScalingWithDefaultAdjustmentType', { + metric: new cloudwatch.Metric({ namespace: 'AWS/EC2', metricName: 'DiskWriteOps', dimensionsMap: { AutoScalingGroupName: asg.autoScalingGroupName } }), + scalingSteps: [ + { upper: 100, change: -1 }, + { lower: 300, change: +1 }, + { lower: 500, change: +2 }, + ], + evaluationPeriods: 10, + datapointsToAlarm: 5, + metricAggregationType: autoscaling.MetricAggregationType.MAXIMUM, +}); new integ.IntegTest(app, 'autoscaling-step-scaling-integ', { testCases: [stack], diff --git a/packages/aws-cdk-lib/aws-apigatewayv2-integrations/README.md b/packages/aws-cdk-lib/aws-apigatewayv2-integrations/README.md index ba8d08d880d55..82a9ea2cd6341 100644 --- a/packages/aws-cdk-lib/aws-apigatewayv2-integrations/README.md +++ b/packages/aws-cdk-lib/aws-apigatewayv2-integrations/README.md @@ -65,6 +65,58 @@ httpApi.addRoutes({ }); ``` +### StepFunctions Integration + +Step Functions integrations enable integrating an HTTP API route with AWS Step Functions. +This allows the HTTP API to start state machine executions synchronously or asynchronously, or to stop executions. + +When a client invokes the route configured with a Step Functions integration, the API Gateway service interacts with the specified state machine according to the integration subtype (e.g., starts a new execution, synchronously starts an execution, or stops an execution) and returns the response to the client. + +The following code configures a Step Functions integrations: + +```ts +import { HttpStepFunctionsIntegration } from 'aws-cdk-lib/aws-apigatewayv2-integrations'; +import * as sfn from 'aws-cdk-lib/aws-stepfunctions'; + +declare const stateMachine: sfn.StateMachine; +declare const httpApi: apigwv2.HttpApi; + +httpApi.addRoutes({ + path: '/start', + methods: [ apigwv2.HttpMethod.POST ], + integration: new HttpStepFunctionsIntegration('StartExecutionIntegration', { + stateMachine, + subtype: apigwv2.HttpIntegrationSubtype.STEPFUNCTIONS_START_EXECUTION, + }), +}); + +httpApi.addRoutes({ + path: '/start-sync', + methods: [ apigwv2.HttpMethod.POST ], + integration: new HttpStepFunctionsIntegration('StartSyncExecutionIntegration', { + stateMachine, + subtype: apigwv2.HttpIntegrationSubtype.STEPFUNCTIONS_START_SYNC_EXECUTION, + }), +}); + +httpApi.addRoutes({ + path: '/stop', + methods: [ apigwv2.HttpMethod.POST ], + integration: new HttpStepFunctionsIntegration('StopExecutionIntegration', { + stateMachine, + subtype: apigwv2.HttpIntegrationSubtype.STEPFUNCTIONS_STOP_EXECUTION, + // For the `STOP_EXECUTION` subtype, it is necessary to specify the `executionArn`. + parameterMapping: new apigwv2.ParameterMapping() + .custom('ExecutionArn', '$request.querystring.executionArn'), + }), +}); +``` + +**Note**: + +- The `executionArn` parameter is required for the `STOP_EXECUTION` subtype. It is necessary to specify the `executionArn` in the `parameterMapping` property of the `HttpStepFunctionsIntegration` object. +- `START_SYNC_EXECUTION` subtype is only supported for EXPRESS type state machine. + ### Private Integration Private integrations enable integrating an HTTP API route with private resources in a VPC, such as Application Load Balancers or diff --git a/packages/aws-cdk-lib/aws-apigatewayv2-integrations/lib/http/index.ts b/packages/aws-cdk-lib/aws-apigatewayv2-integrations/lib/http/index.ts index 8e0598975f8cb..8162b443fc122 100644 --- a/packages/aws-cdk-lib/aws-apigatewayv2-integrations/lib/http/index.ts +++ b/packages/aws-cdk-lib/aws-apigatewayv2-integrations/lib/http/index.ts @@ -4,3 +4,4 @@ export * from './nlb'; export * from './service-discovery'; export * from './http-proxy'; export * from './lambda'; +export * from './stepfunctions'; \ No newline at end of file diff --git a/packages/aws-cdk-lib/aws-apigatewayv2-integrations/lib/http/stepfunctions.ts b/packages/aws-cdk-lib/aws-apigatewayv2-integrations/lib/http/stepfunctions.ts new file mode 100644 index 0000000000000..4229bda171232 --- /dev/null +++ b/packages/aws-cdk-lib/aws-apigatewayv2-integrations/lib/http/stepfunctions.ts @@ -0,0 +1,110 @@ +import * as apigwv2 from '../../../aws-apigatewayv2'; +import * as iam from '../../../aws-iam'; +import * as sfn from '../../../aws-stepfunctions'; + +/** + * Properties to initialize `HttpStepFunctionsIntegration`. + */ +export interface HttpStepFunctionsIntegrationProps { + /** + * Specifies how to transform HTTP requests before sending them to the backend. + * + * When the subtype is either `START_EXECUTION` or `START_SYNC_EXECUTION`, + * it is necessary to specify the `StateMachineArn`. + * Conversely, when the subtype is `STOP_EXECUTION`, the `ExecutionArn` must be specified. + * + * @see https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-parameter-mapping.html + * + * @default - specify only `StateMachineArn` + */ + readonly parameterMapping?: apigwv2.ParameterMapping; + + /** + * The subtype of the HTTP integration. + * + * Only subtypes starting with STEPFUNCTIONS_ can be specified. + * + * @default HttpIntegrationSubtype.STEPFUNCTIONS_START_EXECUTION + */ + readonly subtype?: apigwv2.HttpIntegrationSubtype; + + /** + * Statemachine that Integrates with API Gateway + */ + readonly stateMachine: sfn.StateMachine; +} + +/** + * The StepFunctions integration resource for HTTP API + */ +export class HttpStepFunctionsIntegration extends apigwv2.HttpRouteIntegration { + /** + * @param id id of the underlying integration construct + * @param props properties to configure the integration + */ + constructor( + id: string, + private readonly props: HttpStepFunctionsIntegrationProps, + ) { + super(id); + } + + public bind(options: apigwv2.HttpRouteIntegrationBindOptions): apigwv2.HttpRouteIntegrationConfig { + if (this.props.subtype && !this.props.subtype.startsWith('StepFunctions-')) { + throw new Error('Subtype must start with `STEPFUNCTIONS_`'); + } + if ( + this.props.subtype === apigwv2.HttpIntegrationSubtype.STEPFUNCTIONS_START_SYNC_EXECUTION + && this.props.stateMachine.stateMachineType === sfn.StateMachineType.STANDARD + ) { + throw new Error('Cannot use subtype `STEPFUNCTIONS_START_SYNC_EXECUTION` with a standard type state machine'); + } + + const invokeRole = new iam.Role(options.scope, 'InvokeRole', { + assumedBy: new iam.ServicePrincipal('apigateway.amazonaws.com'), + }); + + invokeRole.addToPolicy( + new iam.PolicyStatement({ + effect: iam.Effect.ALLOW, + sid: 'AllowStepFunctionsExecution', + actions: [this.determineActionBySubtype(this.props.subtype)], + resources: [this.determineResourceArn(options)], + }), + ); + + return { + payloadFormatVersion: apigwv2.PayloadFormatVersion.VERSION_1_0, + type: apigwv2.HttpIntegrationType.AWS_PROXY, + subtype: this.props.subtype ?? apigwv2.HttpIntegrationSubtype.STEPFUNCTIONS_START_EXECUTION, + credentials: apigwv2.IntegrationCredentials.fromRole(invokeRole), + connectionType: apigwv2.HttpConnectionType.INTERNET, + parameterMapping: this.props.parameterMapping ?? new apigwv2.ParameterMapping() + .custom('StateMachineArn', this.props.stateMachine.stateMachineArn), + }; + } + + private determineActionBySubtype(subtype?: apigwv2.HttpIntegrationSubtype): string { + switch (subtype) { + case apigwv2.HttpIntegrationSubtype.STEPFUNCTIONS_STOP_EXECUTION: + return 'states:StopExecution'; + case apigwv2.HttpIntegrationSubtype.STEPFUNCTIONS_START_SYNC_EXECUTION: + return 'states:StartSyncExecution'; + default: + return 'states:StartExecution'; + } + } + + private determineResourceArn(options: apigwv2.HttpRouteIntegrationBindOptions): string { + switch (this.props.subtype) { + case apigwv2.HttpIntegrationSubtype.STEPFUNCTIONS_STOP_EXECUTION: + return options.route.stack.formatArn({ + service: 'states', + resource: `execution:${this.props.stateMachine.stateMachineName}:*`, + }); + // Both START_EXECUTION and START_SYNC_EXECUTION return the state machine arn + default: + return this.props.stateMachine.stateMachineArn; + } + } +} diff --git a/packages/aws-cdk-lib/aws-apigatewayv2-integrations/test/http/stepfunctions.test.ts b/packages/aws-cdk-lib/aws-apigatewayv2-integrations/test/http/stepfunctions.test.ts new file mode 100644 index 0000000000000..1ce6359a26398 --- /dev/null +++ b/packages/aws-cdk-lib/aws-apigatewayv2-integrations/test/http/stepfunctions.test.ts @@ -0,0 +1,228 @@ +import { Match, Template } from '../../../assertions'; +import { HttpApi, HttpIntegrationSubtype, HttpRoute, HttpRouteKey, ParameterMapping } from '../../../aws-apigatewayv2'; +import * as sfn from '../../../aws-stepfunctions'; +import { App, Stack } from '../../../core'; +import { HttpStepFunctionsIntegration } from '../../lib/http/stepfunctions'; + +describe('StepFunctionsIntegration', () => { + test('default', () => { + const app = new App(); + const stack = new Stack(app, 'stack'); + const api = new HttpApi(stack, 'HttpApi'); + const targetStateMachine = new sfn.StateMachine(stack, 'StateMachine', { + definition: new sfn.Pass(stack, 'Pass'), + }); + + new HttpRoute(stack, 'StepFunctionsRoute', { + httpApi: api, + integration: new HttpStepFunctionsIntegration('Integration', { + stateMachine: targetStateMachine, + }), + routeKey: HttpRouteKey.with('/tests'), + }); + + const template = Template.fromStack(stack); + template.hasResourceProperties('AWS::IAM::Role', { + AssumeRolePolicyDocument: { + Statement: Match.arrayWith([ + { + Action: 'sts:AssumeRole', + Effect: 'Allow', + Principal: { + Service: 'apigateway.amazonaws.com', + }, + }, + ]), + }, + }); + template.hasResourceProperties('AWS::IAM::Policy', { + PolicyDocument: { + Statement: [ + { + Action: 'states:StartExecution', + Effect: 'Allow', + Resource: stack.resolve(targetStateMachine.stateMachineArn), + }, + ], + }, + Roles: [ + { + Ref: 'StepFunctionsRouteInvokeRole5E3B5519', + }, + ], + }); + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Integration', { + ConnectionType: 'INTERNET', + CredentialsArn: { + 'Fn::GetAtt': [ + 'StepFunctionsRouteInvokeRole5E3B5519', + 'Arn', + ], + }, + IntegrationType: 'AWS_PROXY', + IntegrationSubtype: 'StepFunctions-StartExecution', + PayloadFormatVersion: '1.0', + RequestParameters: { + StateMachineArn: stack.resolve(targetStateMachine.stateMachineArn), + }, + }); + }); + + test('with parameterMapping', () => { + const app = new App(); + const stack = new Stack(app, 'stack'); + const api = new HttpApi(stack, 'HttpApi'); + const targetStateMachine = new sfn.StateMachine(stack, 'StateMachine', { + definition: new sfn.Pass(stack, 'Pass'), + }); + + new HttpRoute(stack, 'StepFunctionsRoute', { + httpApi: api, + integration: new HttpStepFunctionsIntegration('Integration', { + stateMachine: targetStateMachine, + parameterMapping: new ParameterMapping() + .custom('Input', '$request.body') + .custom('StateMachineArn', targetStateMachine.stateMachineArn), + }), + routeKey: HttpRouteKey.with('/tests'), + }); + + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Integration', { + ConnectionType: 'INTERNET', + CredentialsArn: { + 'Fn::GetAtt': [ + 'StepFunctionsRouteInvokeRole5E3B5519', + 'Arn', + ], + }, + IntegrationType: 'AWS_PROXY', + IntegrationSubtype: 'StepFunctions-StartExecution', + PayloadFormatVersion: '1.0', + RequestParameters: { + Input: '$request.body', + StateMachineArn: stack.resolve(targetStateMachine.stateMachineArn), + }, + }); + }); + + test.each([ + [HttpIntegrationSubtype.STEPFUNCTIONS_START_EXECUTION, 'states:StartExecution', undefined], + [HttpIntegrationSubtype.STEPFUNCTIONS_START_SYNC_EXECUTION, 'states:StartSyncExecution', undefined], + [ + HttpIntegrationSubtype.STEPFUNCTIONS_STOP_EXECUTION, + 'states:StopExecution', + new ParameterMapping().custom('ExecutionArn', '$request.querystring.executionArn'), + ], + ])('with subtype %s', (subtype, action, parameterMapping) => { + const app = new App(); + const stack = new Stack(app, 'stack'); + const api = new HttpApi(stack, 'HttpApi'); + const stateMachine = new sfn.StateMachine(stack, 'StateMachine', { + definition: new sfn.Pass(stack, 'Pass'), + stateMachineType: sfn.StateMachineType.EXPRESS, + }); + + new HttpRoute(stack, 'StepFunctionsRoute', { + httpApi: api, + integration: new HttpStepFunctionsIntegration('Integration', { + stateMachine, + subtype, + parameterMapping, + }), + routeKey: HttpRouteKey.with('/tests'), + }); + + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { + PolicyDocument: { + Statement: [ + { + Action: action, + Effect: 'Allow', + Resource: subtype === HttpIntegrationSubtype.STEPFUNCTIONS_STOP_EXECUTION ? { + 'Fn::Join': [ + '', + [ + 'arn:', + { + Ref: 'AWS::Partition', + }, + ':states:', + { + Ref: 'AWS::Region', + }, + ':', + { + Ref: 'AWS::AccountId', + }, + ':execution:', + { 'Fn::GetAtt': [stack.resolve(stateMachine.stateMachineArn).Ref, 'Name'] }, + ':*', + ], + ], + } : stack.resolve(stateMachine.stateMachineArn), + }, + ], + }, + }); + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Integration', { + ConnectionType: 'INTERNET', + CredentialsArn: { + 'Fn::GetAtt': [ + 'StepFunctionsRouteInvokeRole5E3B5519', + 'Arn', + ], + }, + IntegrationType: 'AWS_PROXY', + IntegrationSubtype: subtype, + PayloadFormatVersion: '1.0', + RequestParameters: { + ...(parameterMapping ? + parameterMapping.mappings : + { StateMachineArn: stack.resolve(stateMachine.stateMachineArn) } + ), + }, + }); + }); + + test('throw error when subtype does not start with STEPFUNCTIONS_', () => { + const app = new App(); + const stack = new Stack(app, 'stack'); + const api = new HttpApi(stack, 'HttpApi'); + const stateMachine = new sfn.StateMachine(stack, 'StateMachine', { + definition: new sfn.Pass(stack, 'Pass'), + }); + + expect(() => { + new HttpRoute(stack, 'StepFunctionsRoute', { + httpApi: api, + integration: new HttpStepFunctionsIntegration('Integration', { + stateMachine, + subtype: HttpIntegrationSubtype.SQS_DELETE_MESSAGE, + }), + routeKey: HttpRouteKey.with('/tests'), + }); + }).toThrow(/Subtype must start with `STEPFUNCTIONS_`/); + }); + + test('throw error when subtype is STEPFUNCTIONS_START_SYNC_EXECUTION with standard state machine', () => { + const app = new App(); + const stack = new Stack(app, 'stack'); + const api = new HttpApi(stack, 'HttpApi'); + const stateMachine = new sfn.StateMachine(stack, 'StateMachine', { + definition: new sfn.Pass(stack, 'Pass'), + stateMachineType: sfn.StateMachineType.STANDARD, + }); + + expect(() => { + new HttpRoute(stack, 'StepFunctionsRoute', { + httpApi: api, + integration: new HttpStepFunctionsIntegration('Integration', { + stateMachine, + subtype: HttpIntegrationSubtype.STEPFUNCTIONS_START_SYNC_EXECUTION, + }), + routeKey: HttpRouteKey.with('/tests'), + }); + }).toThrow(/Cannot use subtype `STEPFUNCTIONS_START_SYNC_EXECUTION` with a standard type state machine/); + }); +}); + diff --git a/packages/aws-cdk-lib/aws-appsync/README.md b/packages/aws-cdk-lib/aws-appsync/README.md index d24828f11ff80..119b139ff0721 100644 --- a/packages/aws-cdk-lib/aws-appsync/README.md +++ b/packages/aws-cdk-lib/aws-appsync/README.md @@ -632,7 +632,7 @@ Use the `grant` function for more granular authorization. const role = new iam.Role(this, 'Role', { assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'), }); -declare const api: appsync.GraphqlApi; +declare const api: appsync.IGraphqlApi; api.grant(role, appsync.IamResource.custom('types/Mutation/fields/updateExample'), 'appsync:GraphQL'); ``` @@ -658,7 +658,7 @@ These include: - grantSubscription (use to grant access to Subscription fields) ```ts -declare const api: appsync.GraphqlApi; +declare const api: appsync.IGraphqlApi; declare const role: iam.Role; // For generic types diff --git a/packages/aws-cdk-lib/aws-appsync/lib/graphqlapi-base.ts b/packages/aws-cdk-lib/aws-appsync/lib/graphqlapi-base.ts index f4acb601aa7bd..a75657f80a1a8 100644 --- a/packages/aws-cdk-lib/aws-appsync/lib/graphqlapi-base.ts +++ b/packages/aws-cdk-lib/aws-appsync/lib/graphqlapi-base.ts @@ -13,11 +13,12 @@ import { Resolver, ExtendedResolverProps } from './resolver'; import { ITable } from '../../aws-dynamodb'; import { IDomain as IElasticsearchDomain } from '../../aws-elasticsearch'; import { IEventBus } from '../../aws-events'; +import { Grant, IGrantable } from '../../aws-iam'; import { IFunction } from '../../aws-lambda'; import { IDomain as IOpenSearchDomain } from '../../aws-opensearchservice'; import { IServerlessCluster } from '../../aws-rds'; import { ISecret } from '../../aws-secretsmanager'; -import { CfnResource, IResource, Resource } from '../../core'; +import { ArnFormat, CfnResource, IResource, Resource, Stack } from '../../core'; /** * Optional configuration for data sources @@ -50,6 +51,67 @@ export interface HttpDataSourceOptions extends DataSourceOptions { readonly authorizationConfig?: AwsIamConfig; } +/** + * A class used to generate resource arns for AppSync + */ +export class IamResource { + /** + * Generate the resource names given custom arns + * + * @param arns The custom arns that need to be permissioned + * + * Example: custom('/types/Query/fields/getExample') + */ + public static custom(...arns: string[]): IamResource { + if (arns.length === 0) { + throw new Error('At least 1 custom ARN must be provided.'); + } + return new IamResource(arns); + } + + /** + * Generate the resource names given a type and fields + * + * @param type The type that needs to be allowed + * @param fields The fields that need to be allowed, if empty grant permissions to ALL fields + * + * Example: ofType('Query', 'GetExample') + */ + public static ofType(type: string, ...fields: string[]): IamResource { + const arns = fields.length ? fields.map((field) => `types/${type}/fields/${field}`) : [`types/${type}/*`]; + return new IamResource(arns); + } + + /** + * Generate the resource names that accepts all types: `*` + */ + public static all(): IamResource { + return new IamResource(['*']); + } + + private arns: string[]; + + private constructor(arns: string[]) { + this.arns = arns; + } + + /** + * Return the Resource ARN + * + * @param api The GraphQL API to give permissions + */ + public resourceArns(api: GraphqlApiBase): string[] { + return this.arns.map((arn) => + Stack.of(api).formatArn({ + service: 'appsync', + resource: `apis/${api.apiId}`, + arnFormat: ArnFormat.SLASH_RESOURCE_NAME, + resourceName: `${arn}`, + }), + ); + } +} + /** * Interface for GraphQL */ @@ -161,6 +223,43 @@ export interface IGraphqlApi extends IResource { * @param construct the dependee */ addSchemaDependency(construct: CfnResource): boolean; + + /** + * Adds an IAM policy statement associated with this GraphQLApi to an IAM + * principal's policy. + * + * @param grantee The principal + * @param resources The set of resources to allow (i.e. ...:[region]:[accountId]:apis/GraphQLId/...) + * @param actions The actions that should be granted to the principal (i.e. appsync:graphql ) + */ + grant(grantee: IGrantable, resources: IamResource, ...actions: string[]): Grant; + + /** + * Adds an IAM policy statement for Mutation access to this GraphQLApi to an IAM + * principal's policy. + * + * @param grantee The principal + * @param fields The fields to grant access to that are Mutations (leave blank for all) + */ + grantMutation(grantee: IGrantable, ...fields: string[]): Grant; + + /** + * Adds an IAM policy statement for Query access to this GraphQLApi to an IAM + * principal's policy. + * + * @param grantee The principal + * @param fields The fields to grant access to that are Queries (leave blank for all) + */ + grantQuery(grantee: IGrantable, ...fields: string[]): Grant; + + /** + * Adds an IAM policy statement for Subscription access to this GraphQLApi to an IAM + * principal's policy. + * + * @param grantee The principal + * @param fields The fields to grant access to that are Subscriptions (leave blank for all) + */ + grantSubscription(grantee: IGrantable, ...fields: string[]): Grant; } /** @@ -335,4 +434,54 @@ export abstract class GraphqlApiBase extends Resource implements IGraphqlApi { construct; return false; } + + /** + * Adds an IAM policy statement associated with this GraphQLApi to an IAM + * principal's policy. + * + * @param grantee The principal + * @param resources The set of resources to allow (i.e. ...:[region]:[accountId]:apis/GraphQLId/...) + * @param actions The actions that should be granted to the principal (i.e. appsync:graphql ) + */ + public grant(grantee: IGrantable, resources: IamResource, ...actions: string[]): Grant { + return Grant.addToPrincipal({ + grantee, + actions, + resourceArns: resources.resourceArns(this), + scope: this, + }); + } + + /** + * Adds an IAM policy statement for Mutation access to this GraphQLApi to an IAM + * principal's policy. + * + * @param grantee The principal + * @param fields The fields to grant access to that are Mutations (leave blank for all) + */ + public grantMutation(grantee: IGrantable, ...fields: string[]): Grant { + return this.grant(grantee, IamResource.ofType('Mutation', ...fields), 'appsync:GraphQL'); + } + + /** + * Adds an IAM policy statement for Query access to this GraphQLApi to an IAM + * principal's policy. + * + * @param grantee The principal + * @param fields The fields to grant access to that are Queries (leave blank for all) + */ + public grantQuery(grantee: IGrantable, ...fields: string[]): Grant { + return this.grant(grantee, IamResource.ofType('Query', ...fields), 'appsync:GraphQL'); + } + + /** + * Adds an IAM policy statement for Subscription access to this GraphQLApi to an IAM + * principal's policy. + * + * @param grantee The principal + * @param fields The fields to grant access to that are Subscriptions (leave blank for all) + */ + public grantSubscription(grantee: IGrantable, ...fields: string[]): Grant { + return this.grant(grantee, IamResource.ofType('Subscription', ...fields), 'appsync:GraphQL'); + } } diff --git a/packages/aws-cdk-lib/aws-appsync/lib/graphqlapi.ts b/packages/aws-cdk-lib/aws-appsync/lib/graphqlapi.ts index 04b6ed99b793d..75420814843b7 100644 --- a/packages/aws-cdk-lib/aws-appsync/lib/graphqlapi.ts +++ b/packages/aws-cdk-lib/aws-appsync/lib/graphqlapi.ts @@ -5,10 +5,10 @@ import { ISchema, SchemaFile } from './schema'; import { MergeType, addSourceApiAutoMergePermission, addSourceGraphQLPermission } from './source-api-association'; import { ICertificate } from '../../aws-certificatemanager'; import { IUserPool } from '../../aws-cognito'; -import { ManagedPolicy, Role, IRole, ServicePrincipal, Grant, IGrantable } from '../../aws-iam'; +import { ManagedPolicy, Role, IRole, ServicePrincipal } from '../../aws-iam'; import { IFunction } from '../../aws-lambda'; import { ILogGroup, LogGroup, LogRetention, RetentionDays } from '../../aws-logs'; -import { ArnFormat, CfnResource, Duration, Expiration, FeatureFlags, IResolvable, Lazy, Stack, Token } from '../../core'; +import { CfnResource, Duration, Expiration, FeatureFlags, IResolvable, Lazy, Stack, Token } from '../../core'; import * as cxapi from '../../cx-api'; /** @@ -458,65 +458,6 @@ export interface GraphqlApiProps { readonly environmentVariables?: { [key: string]: string }; } -/** - * A class used to generate resource arns for AppSync - */ -export class IamResource { - /** - * Generate the resource names given custom arns - * - * @param arns The custom arns that need to be permissioned - * - * Example: custom('/types/Query/fields/getExample') - */ - public static custom(...arns: string[]): IamResource { - if (arns.length === 0) { - throw new Error('At least 1 custom ARN must be provided.'); - } - return new IamResource(arns); - } - - /** - * Generate the resource names given a type and fields - * - * @param type The type that needs to be allowed - * @param fields The fields that need to be allowed, if empty grant permissions to ALL fields - * - * Example: ofType('Query', 'GetExample') - */ - public static ofType(type: string, ...fields: string[]): IamResource { - const arns = fields.length ? fields.map((field) => `types/${type}/fields/${field}`) : [`types/${type}/*`]; - return new IamResource(arns); - } - - /** - * Generate the resource names that accepts all types: `*` - */ - public static all(): IamResource { - return new IamResource(['*']); - } - - private arns: string[]; - - private constructor(arns: string[]) { - this.arns = arns; - } - - /** - * Return the Resource ARN - * - * @param api The GraphQL API to give permissions - */ - public resourceArns(api: GraphqlApi): string[] { - return this.arns.map((arn) => Stack.of(api).formatArn({ - service: 'appsync', - resource: `apis/${api.apiId}`, - arnFormat: ArnFormat.SLASH_RESOURCE_NAME, - resourceName: `${arn}`, - })); - } -} - /** * Attributes for GraphQL imports */ @@ -785,56 +726,6 @@ export class GraphqlApi extends GraphqlApiBase { } } - /** - * Adds an IAM policy statement associated with this GraphQLApi to an IAM - * principal's policy. - * - * @param grantee The principal - * @param resources The set of resources to allow (i.e. ...:[region]:[accountId]:apis/GraphQLId/...) - * @param actions The actions that should be granted to the principal (i.e. appsync:graphql ) - */ - public grant(grantee: IGrantable, resources: IamResource, ...actions: string[]): Grant { - return Grant.addToPrincipal({ - grantee, - actions, - resourceArns: resources.resourceArns(this), - scope: this, - }); - } - - /** - * Adds an IAM policy statement for Mutation access to this GraphQLApi to an IAM - * principal's policy. - * - * @param grantee The principal - * @param fields The fields to grant access to that are Mutations (leave blank for all) - */ - public grantMutation(grantee: IGrantable, ...fields: string[]): Grant { - return this.grant(grantee, IamResource.ofType('Mutation', ...fields), 'appsync:GraphQL'); - } - - /** - * Adds an IAM policy statement for Query access to this GraphQLApi to an IAM - * principal's policy. - * - * @param grantee The principal - * @param fields The fields to grant access to that are Queries (leave blank for all) - */ - public grantQuery(grantee: IGrantable, ...fields: string[]): Grant { - return this.grant(grantee, IamResource.ofType('Query', ...fields), 'appsync:GraphQL'); - } - - /** - * Adds an IAM policy statement for Subscription access to this GraphQLApi to an IAM - * principal's policy. - * - * @param grantee The principal - * @param fields The fields to grant access to that are Subscriptions (leave blank for all) - */ - public grantSubscription(grantee: IGrantable, ...fields: string[]): Grant { - return this.grant(grantee, IamResource.ofType('Subscription', ...fields), 'appsync:GraphQL'); - } - private validateAuthorizationProps(modes: AuthorizationMode[]) { if (modes.filter((mode) => mode.authorizationType === AuthorizationType.LAMBDA).length > 1) { throw new Error('You can only have a single AWS Lambda function configured to authorize your API.'); diff --git a/packages/aws-cdk-lib/aws-appsync/test/appsync-grant.test.ts b/packages/aws-cdk-lib/aws-appsync/test/appsync-grant.test.ts index e6ad4a1741238..0c89126a34a90 100644 --- a/packages/aws-cdk-lib/aws-appsync/test/appsync-grant.test.ts +++ b/packages/aws-cdk-lib/aws-appsync/test/appsync-grant.test.ts @@ -578,4 +578,590 @@ describe('grantSubscription Permissions', () => { }, }); }); +}); + +describe('imported API', () => { + let importedApi: appsync.IGraphqlApi; + beforeEach(() => { + importedApi = appsync.GraphqlApi.fromGraphqlApiAttributes(stack, 'imported', { + graphqlApiId: 'importedId', + }); + }); + + describe('grant Permissions', () => { + test('IamResource throws error when custom is called with no arguments', () => { + //THEN + expect(() => { + importedApi.grant(role, appsync.IamResource.custom(), 'appsync:GraphQL'); + }).toThrow('At least 1 custom ARN must be provided.'); + }); + + test('grant provides custom permissions when called with `custom` argument', () => { + // WHEN + importedApi.grant( + role, + appsync.IamResource.custom('types/Mutation/fields/addTest'), + 'appsync:GraphQL', + ); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { + PolicyDocument: { + Statement: [ + { + Action: 'appsync:GraphQL', + Effect: 'Allow', + Resource: { + 'Fn::Join': [ + '', + [ + 'arn:', + { Ref: 'AWS::Partition' }, + ':appsync:', + { Ref: 'AWS::Region' }, + ':', + { Ref: 'AWS::AccountId' }, + ':apis/importedId/types/Mutation/fields/addTest', + ], + ], + }, + }, + ], + }, + }); + }); + + test('grant provides [type parameter]/* permissions when called with `type` argument', () => { + // WHEN + importedApi.grant(role, appsync.IamResource.ofType('Mutation'), 'appsync:GraphQL'); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { + PolicyDocument: { + Statement: [ + { + Action: 'appsync:GraphQL', + Effect: 'Allow', + Resource: { + 'Fn::Join': [ + '', + [ + 'arn:', + { Ref: 'AWS::Partition' }, + ':appsync:', + { Ref: 'AWS::Region' }, + ':', + { Ref: 'AWS::AccountId' }, + ':apis/importedId/types/Mutation/*', + ], + ], + }, + }, + ], + }, + }); + }); + + test('grant provides fields/[field param] permissions when called with `type` and `field` argument', () => { + // WHEN + importedApi.grant(role, appsync.IamResource.ofType('Mutation', 'addTest'), 'appsync:GraphQL'); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { + PolicyDocument: { + Statement: [ + { + Action: 'appsync:GraphQL', + Effect: 'Allow', + Resource: { + 'Fn::Join': [ + '', + [ + 'arn:', + { Ref: 'AWS::Partition' }, + ':appsync:', + { Ref: 'AWS::Region' }, + ':', + { Ref: 'AWS::AccountId' }, + ':apis/importedId/types/Mutation/fields/addTest', + ], + ], + }, + }, + ], + }, + }); + }); + + test('grant provides all permissions when called with IamResource.all()', () => { + // WHEN + importedApi.grant(role, appsync.IamResource.all(), 'appsync:GraphQL'); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { + PolicyDocument: { + Statement: [ + { + Action: 'appsync:GraphQL', + Effect: 'Allow', + Resource: { + 'Fn::Join': [ + '', + [ + 'arn:', + { Ref: 'AWS::Partition' }, + ':appsync:', + { Ref: 'AWS::Region' }, + ':', + { Ref: 'AWS::AccountId' }, + ':apis/importedId/*', + ], + ], + }, + }, + ], + }, + }); + }); + + test('grant provides multiple permissions using one IamResource custom call', () => { + // WHEN + importedApi.grant(role, appsync.IamResource.custom('I', 'am', 'custom'), 'appsync:GraphQL'); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { + PolicyDocument: { + Statement: [ + { + Action: 'appsync:GraphQL', + Effect: 'Allow', + Resource: [ + { + 'Fn::Join': [ + '', + [ + 'arn:', + { Ref: 'AWS::Partition' }, + ':appsync:', + { Ref: 'AWS::Region' }, + ':', + { Ref: 'AWS::AccountId' }, + ':apis/importedId/I', + ], + ], + }, + { + 'Fn::Join': [ + '', + [ + 'arn:', + { Ref: 'AWS::Partition' }, + ':appsync:', + { Ref: 'AWS::Region' }, + ':', + { Ref: 'AWS::AccountId' }, + ':apis/importedId/am', + ], + ], + }, + { + 'Fn::Join': [ + '', + [ + 'arn:', + { Ref: 'AWS::Partition' }, + ':appsync:', + { Ref: 'AWS::Region' }, + ':', + { Ref: 'AWS::AccountId' }, + ':apis/importedId/custom', + ], + ], + }, + ], + }, + ], + }, + }); + }); + + test('grant provides multiple permissions using one IamResource ofType call', () => { + // WHEN + importedApi.grant(role, appsync.IamResource.ofType('I', 'am', 'custom'), 'appsync:GraphQL'); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { + PolicyDocument: { + Statement: [ + { + Action: 'appsync:GraphQL', + Effect: 'Allow', + Resource: [ + { + 'Fn::Join': [ + '', + [ + 'arn:', + { Ref: 'AWS::Partition' }, + ':appsync:', + { Ref: 'AWS::Region' }, + ':', + { Ref: 'AWS::AccountId' }, + ':apis/importedId/types/I/fields/am', + ], + ], + }, + { + 'Fn::Join': [ + '', + [ + 'arn:', + { Ref: 'AWS::Partition' }, + ':appsync:', + { Ref: 'AWS::Region' }, + ':', + { Ref: 'AWS::AccountId' }, + ':apis/importedId/types/I/fields/custom', + ], + ], + }, + ], + }, + ], + }, + }); + }); + }); + + describe('grantMutation Permissions', () => { + test('grantMutation provides Mutation/* permissions when called with no `fields` argument', () => { + // WHEN + importedApi.grantMutation(role); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { + PolicyDocument: { + Statement: [ + { + Action: 'appsync:GraphQL', + Effect: 'Allow', + Resource: { + 'Fn::Join': [ + '', + [ + 'arn:', + { Ref: 'AWS::Partition' }, + ':appsync:', + { Ref: 'AWS::Region' }, + ':', + { Ref: 'AWS::AccountId' }, + ':apis/importedId/types/Mutation/*', + ], + ], + }, + }, + ], + }, + }); + }); + + test('grantMutation provides fields/[field param] permissions when called with `fields` argument', () => { + // WHEN + importedApi.grantMutation(role, 'addTest'); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { + PolicyDocument: { + Statement: [ + { + Action: 'appsync:GraphQL', + Effect: 'Allow', + Resource: { + 'Fn::Join': [ + '', + [ + 'arn:', + { Ref: 'AWS::Partition' }, + ':appsync:', + { Ref: 'AWS::Region' }, + ':', + { Ref: 'AWS::AccountId' }, + ':apis/importedId/types/Mutation/fields/addTest', + ], + ], + }, + }, + ], + }, + }); + }); + + test('grantMutation provides multiple permissions when called with `fields` argument', () => { + // WHEN + importedApi.grantMutation(role, 'addTest', 'removeTest'); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { + PolicyDocument: { + Statement: [ + { + Action: 'appsync:GraphQL', + Effect: 'Allow', + Resource: [ + { + 'Fn::Join': [ + '', + [ + 'arn:', + { Ref: 'AWS::Partition' }, + ':appsync:', + { Ref: 'AWS::Region' }, + ':', + { Ref: 'AWS::AccountId' }, + ':apis/importedId/types/Mutation/fields/addTest', + ], + ], + }, + { + 'Fn::Join': [ + '', + [ + 'arn:', + { Ref: 'AWS::Partition' }, + ':appsync:', + { Ref: 'AWS::Region' }, + ':', + { Ref: 'AWS::AccountId' }, + ':apis/importedId/types/Mutation/fields/removeTest', + ], + ], + }, + ], + }, + ], + }, + }); + }); + }); + + describe('grantQuery Permissions', () => { + test('grantQuery provides Query/* permissions when called without the `fields` argument', () => { + // WHEN + importedApi.grantQuery(role); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { + PolicyDocument: { + Statement: [ + { + Action: 'appsync:GraphQL', + Effect: 'Allow', + Resource: { + 'Fn::Join': [ + '', + [ + 'arn:', + { Ref: 'AWS::Partition' }, + ':appsync:', + { Ref: 'AWS::Region' }, + ':', + { Ref: 'AWS::AccountId' }, + ':apis/importedId/types/Query/*', + ], + ], + }, + }, + ], + }, + }); + }); + + test('grantQuery provides fields/[field param] permissions when called with `fields` arugment', () => { + // WHEN + importedApi.grantQuery(role, 'getTest'); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { + PolicyDocument: { + Statement: [ + { + Action: 'appsync:GraphQL', + Effect: 'Allow', + Resource: { + 'Fn::Join': [ + '', + [ + 'arn:', + { Ref: 'AWS::Partition' }, + ':appsync:', + { Ref: 'AWS::Region' }, + ':', + { Ref: 'AWS::AccountId' }, + ':apis/importedId/types/Query/fields/getTest', + ], + ], + }, + }, + ], + }, + }); + }); + + test('grantQuery provides multiple permissions when called with `fields` argument', () => { + // WHEN + importedApi.grantQuery(role, 'getTests', 'getTest'); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { + PolicyDocument: { + Statement: [ + { + Action: 'appsync:GraphQL', + Effect: 'Allow', + Resource: [ + { + 'Fn::Join': [ + '', + [ + 'arn:', + { Ref: 'AWS::Partition' }, + ':appsync:', + { Ref: 'AWS::Region' }, + ':', + { Ref: 'AWS::AccountId' }, + ':apis/importedId/types/Query/fields/getTests', + ], + ], + }, + { + 'Fn::Join': [ + '', + [ + 'arn:', + { Ref: 'AWS::Partition' }, + ':appsync:', + { Ref: 'AWS::Region' }, + ':', + { Ref: 'AWS::AccountId' }, + ':apis/importedId/types/Query/fields/getTest', + ], + ], + }, + ], + }, + ], + }, + }); + }); + }); + + describe('grantSubscription Permissions', () => { + test('grantSubscription provides Subscription/* permissions when called without `fields` argument', () => { + // WHEN + importedApi.grantSubscription(role); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { + PolicyDocument: { + Statement: [ + { + Action: 'appsync:GraphQL', + Effect: 'Allow', + Resource: { + 'Fn::Join': [ + '', + [ + 'arn:', + { Ref: 'AWS::Partition' }, + ':appsync:', + { Ref: 'AWS::Region' }, + ':', + { Ref: 'AWS::AccountId' }, + ':apis/importedId/types/Subscription/*', + ], + ], + }, + }, + ], + }, + }); + }); + + test('grantSubscription provides fields/[field param] when called with `field` argument', () => { + importedApi.grantSubscription(role, 'subscribe'); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { + PolicyDocument: { + Statement: [ + { + Action: 'appsync:GraphQL', + Effect: 'Allow', + Resource: { + 'Fn::Join': [ + '', + [ + 'arn:', + { Ref: 'AWS::Partition' }, + ':appsync:', + { Ref: 'AWS::Region' }, + ':', + { Ref: 'AWS::AccountId' }, + ':apis/importedId/types/Subscription/fields/subscribe', + ], + ], + }, + }, + ], + }, + }); + }); + + test('grantSubscription provides multiple permissions when called with `fields` argument', () => { + // WHEN + importedApi.grantSubscription(role, 'subscribe', 'custom'); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { + PolicyDocument: { + Statement: [ + { + Action: 'appsync:GraphQL', + Effect: 'Allow', + Resource: [ + { + 'Fn::Join': [ + '', + [ + 'arn:', + { Ref: 'AWS::Partition' }, + ':appsync:', + { Ref: 'AWS::Region' }, + ':', + { Ref: 'AWS::AccountId' }, + ':apis/importedId/types/Subscription/fields/subscribe', + ], + ], + }, + { + 'Fn::Join': [ + '', + [ + 'arn:', + { Ref: 'AWS::Partition' }, + ':appsync:', + { Ref: 'AWS::Region' }, + ':', + { Ref: 'AWS::AccountId' }, + ':apis/importedId/types/Subscription/fields/custom', + ], + ], + }, + ], + }, + ], + }, + }); + }); + }); }); \ No newline at end of file diff --git a/packages/aws-cdk-lib/aws-autoscaling/lib/step-scaling-policy.ts b/packages/aws-cdk-lib/aws-autoscaling/lib/step-scaling-policy.ts index eed4950e7e720..937c92c0b80b1 100644 --- a/packages/aws-cdk-lib/aws-autoscaling/lib/step-scaling-policy.ts +++ b/packages/aws-cdk-lib/aws-autoscaling/lib/step-scaling-policy.ts @@ -147,7 +147,7 @@ export class StepScalingPolicy extends Construct { const threshold = intervals[alarms.lowerAlarmIntervalIndex].upper; this.lowerAction = new StepScalingAction(this, 'LowerPolicy', { - adjustmentType: props.adjustmentType, + adjustmentType, cooldown: props.cooldown, estimatedInstanceWarmup: props.estimatedInstanceWarmup, metricAggregationType: props.metricAggregationType ?? aggregationTypeFromMetric(props.metric), @@ -179,7 +179,7 @@ export class StepScalingPolicy extends Construct { const threshold = intervals[alarms.upperAlarmIntervalIndex].lower; this.upperAction = new StepScalingAction(this, 'UpperPolicy', { - adjustmentType: props.adjustmentType, + adjustmentType, cooldown: props.cooldown, estimatedInstanceWarmup: props.estimatedInstanceWarmup, metricAggregationType: props.metricAggregationType ?? aggregationTypeFromMetric(props.metric), diff --git a/packages/aws-cdk-lib/aws-autoscaling/test/scaling.test.ts b/packages/aws-cdk-lib/aws-autoscaling/test/scaling.test.ts index dc4a564d75221..f8dd19b431812 100644 --- a/packages/aws-cdk-lib/aws-autoscaling/test/scaling.test.ts +++ b/packages/aws-cdk-lib/aws-autoscaling/test/scaling.test.ts @@ -294,6 +294,28 @@ test('step scaling from percentile metric', () => { }); }); +test('step scaling with adjustmentType by default', () => { + // GIVEN + const stack = new cdk.Stack(); + const fixture = new ASGFixture(stack, 'Fixture'); + + // WHEN + fixture.asg.scaleOnMetric('Tracking', { + metric: new cloudwatch.Metric({ namespace: 'Test', metricName: 'Metric', statistic: 'p99' }), + scalingSteps: [ + { upper: 0, change: -1 }, + { lower: 100, change: +1 }, + { lower: 500, change: +5 }, + ], + }); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::AutoScaling::ScalingPolicy', { + PolicyType: 'StepScaling', + AdjustmentType: 'ChangeInCapacity', + }); +}); + test('step scaling with evaluation period configured', () => { // GIVEN const stack = new cdk.Stack(); diff --git a/packages/aws-cdk-lib/aws-eks/README.md b/packages/aws-cdk-lib/aws-eks/README.md index 081743a3d0d75..f5d2c00c9aca3 100644 --- a/packages/aws-cdk-lib/aws-eks/README.md +++ b/packages/aws-cdk-lib/aws-eks/README.md @@ -15,6 +15,7 @@ In addition, the library also supports defining Kubernetes resource manifests wi - [Node Groups with IPv6 Support](#node-groups-with-ipv6-support) - [Spot Instances Support](#spot-instances-support) - [Launch Template Support](#launch-template-support) + - [Update clusters](#update-clusters) - [Fargate profiles](#fargate-profiles) - [Self-managed nodes](#self-managed-nodes) - [Spot Instances](#spot-instances) @@ -366,6 +367,29 @@ You may specify one `instanceType` in the launch template or multiple `instanceT Graviton 2 instance types are supported including `c6g`, `m6g`, `r6g` and `t4g`. Graviton 3 instance types are supported including `c7g`. +### Update clusters + +When you rename the cluster name and redeploy the stack, the cluster replacement will be triggered and +the existing one will be deleted after the new one is provisioned. As the cluster resource ARN has been changed, +the cluster resource handler would not be able to delete the old one as the resource ARN in the IAM policy +has been changed. As a workaround, you need to add a temporary policy to the cluster admin role for +successful replacement. Consider this example if you are renaming the cluster from `foo` to `bar`: + +```ts +const cluster = new eks.Cluster(this, 'cluster-to-rename', { + clusterName: 'foo', // rename this to 'bar' + version: eks.KubernetesVersion.V1_29, +}); + +// allow the cluster admin role to delete the cluster 'foo' +cluster.adminRole.addToPolicy(new iam.PolicyStatement({ + actions: ['eks:DeleteCluster'], + resources: [ + Stack.of(this).formatArn({ service: 'eks', resource: 'cluster', resourceName: 'foo' }), +] +})) +``` + ### Fargate profiles AWS Fargate is a technology that provides on-demand, right-sized compute