diff --git a/DEVELOPMENT_GUIDE.md b/DEVELOPMENT_GUIDE.md index aa7dc982b..6d3ecac38 100644 --- a/DEVELOPMENT_GUIDE.md +++ b/DEVELOPMENT_GUIDE.md @@ -134,27 +134,16 @@ one python version locally and then have our ci (appveyor) run all supported ver Transform tests ensure a SAM template transforms into the expected CloudFormation template. -When adding new transform tests, we have provided a script to help generate the transform test input -and output files in the correct directory given a `template.yaml` file. -```bash -python3 bin/add_transform_test.py --template-file template.yaml -``` - -This script will automatically generate the input and output files. It will guarantee that the output -files have the correct AWS partition (e.g. aws-cn, aws-us-gov). +We provide a script to help generate the transform test input +and output files in the correct directory given a SAM template. For example: -For `AWS::ApiGateway::RestApi`, the script will automatically append `REGIONAL` `EndpointConfiguration`. -To disable this feature, run the following command instead. ```bash -python3 bin/add_transform_test.py --template-file template.yaml --disable-api-configuration -``` - -The script automatically updates hardcoded ARN partitions to match the output partition. To disable this, use: -```bash -python3 bin/add_transform_test.py --template-file template.yaml --disable-update-partition +python3 bin/add_transform_test.py --template-file template.yaml ``` -Please always check the generated output is as expected. This tool does not guarantee correct output. +> **Warning** +> +> Always check the generated output is as expected. This tool does not guarantee correct output. #### Transform failures diff --git a/bin/add_transform_test.py b/bin/add_transform_test.py index d2286e50a..99139b74e 100755 --- a/bin/add_transform_test.py +++ b/bin/add_transform_test.py @@ -8,10 +8,10 @@ from copy import deepcopy from pathlib import Path from typing import Any, Dict +from unittest.mock import patch import boto3 -from samtranslator.translator.arn_generator import ArnGenerator from samtranslator.translator.managed_policy_translator import ManagedPolicyLoader from samtranslator.translator.transform import transform from samtranslator.yaml_helper import yaml_parse @@ -28,16 +28,6 @@ type=Path, default=Path("template.yaml"), ) -parser.add_argument( - "--disable-api-configuration", - help="Disable adding REGIONAL configuration to AWS::ApiGateway::RestApi", - action="store_true", -) -parser.add_argument( - "--disable-update-partition", - help="Disable updating the partition of arn to aws-cn/aws-us-gov", - action="store_true", -) CLI_OPTIONS = parser.parse_args() @@ -51,25 +41,6 @@ def write_json_file(obj: Dict[str, Any], file_path: Path) -> None: json.dump(obj, f, indent=2, sort_keys=True) -def add_regional_endpoint_configuration_if_needed(template: Dict[str, Any]) -> Dict[str, Any]: - for _, resource in template["Resources"].items(): - if resource["Type"] == "AWS::ApiGateway::RestApi": - properties = resource["Properties"] - if "EndpointConfiguration" not in properties: - properties["EndpointConfiguration"] = {"Types": ["REGIONAL"]} - if "Parameters" not in properties: - properties["Parameters"] = {"endpointConfigurationTypes": "REGIONAL"} - - return template - - -def replace_aws_partition(partition: str, file_path: Path) -> None: - template = read_json_file(file_path) - updated_template = json.loads(json.dumps(template).replace("arn:aws:", f"arn:{partition}:")) - file_path.write_text(json.dumps(updated_template, indent=2), encoding="utf-8") - print(f"Transform Test output files generated {file_path}") - - def generate_transform_test_output_files(input_file_path: Path, file_basename: str) -> None: output_file_option = file_basename + ".json" @@ -82,20 +53,13 @@ def generate_transform_test_output_files(input_file_path: Path, file_basename: s "aws-us-gov": ("us-gov-west-1", TRANSFORM_TEST_DIR / "output" / "aws-us-gov" / output_file_option), } - for partition, (region, output_path) in transform_test_output_paths.items(): - # Set Boto Session Region to guarantee the same hash input as transform tests for API deployment id - ArnGenerator.BOTO_SESSION_REGION_NAME = region - # Implicit API Plugin may alter input template file, thus passing a copy here. - output_fragment = transform(deepcopy(manifest), {}, ManagedPolicyLoader(iam_client)) - - if not CLI_OPTIONS.disable_api_configuration and partition != "aws": - output_fragment = add_regional_endpoint_configuration_if_needed(output_fragment) - - write_json_file(output_fragment, output_path) - - # Update arn partition if necessary - if not CLI_OPTIONS.disable_update_partition: - replace_aws_partition(partition, output_path) + for _, (region, output_path) in transform_test_output_paths.items(): + with patch("samtranslator.translator.arn_generator._get_region_from_session", return_value=region), patch( + "boto3.session.Session.region_name", region + ): + # Implicit API Plugin may alter input template file, thus passing a copy here. + output_fragment = transform(deepcopy(manifest), {}, ManagedPolicyLoader(iam_client)) + write_json_file(output_fragment, output_path) def get_input_file_path() -> Path: diff --git a/tests/translator/input/api_with_custom_domains_regional.yaml b/tests/translator/input/api_with_custom_domains_regional.yaml new file mode 100644 index 000000000..089ce14f6 --- /dev/null +++ b/tests/translator/input/api_with_custom_domains_regional.yaml @@ -0,0 +1,54 @@ +Parameters: + MyRestRegionalDomainName: + Type: String + MyRestRegionalDomainCert: + Type: String + HostedZoneId: + Type: String + +Globals: + Api: + Domain: + DomainName: + Ref: MyRestRegionalDomainName + CertificateArn: + Ref: MyRestRegionalDomainCert + EndpointConfiguration: REGIONAL + MutualTlsAuthentication: + TruststoreUri: ${mtlsuri} + TruststoreVersion: 0 + SecurityPolicy: TLS_1_2 + BasePath: + - /get + - /post + Route53: + HostedZoneId: + Ref: HostedZoneId + +Resources: + MyFunction: + Type: AWS::Serverless::Function + Properties: + InlineCode: | + exports.handler = async (event) => { + const response = { + statusCode: 200, + body: JSON.stringify('Hello from Lambda!'), + }; + return response; + }; + Handler: index.handler + Runtime: nodejs14.x + Events: + ImplicitGet: + Type: Api + Properties: + Method: Get + Path: /get + ImplicitPost: + Type: Api + Properties: + Method: Post + Path: /post +Metadata: + SamTransformTest: true diff --git a/tests/translator/input/basic_state_machine_with_tags.yaml b/tests/translator/input/basic_state_machine_with_tags.yaml new file mode 100644 index 000000000..550ff1fa4 --- /dev/null +++ b/tests/translator/input/basic_state_machine_with_tags.yaml @@ -0,0 +1,35 @@ +Resources: + MyStateMachine: + Type: AWS::Serverless::StateMachine + Properties: + Definition: + Comment: A Hello World example of the Amazon States Language using Pass states + StartAt: Hello + States: + Hello: + Type: Pass + Result: Hello + Next: World + World: + Type: Pass + Result: World + End: true + Policies: + - Version: '2012-10-17' + Statement: + - Effect: Deny + Action: '*' + Resource: '*' + Tags: + TagOne: ValueOne + TagTwo: ValueTwo + Tracing: + Enabled: true + +Outputs: + MyStateMachineArn: + Description: ARN of the state machine + Value: + Ref: MyStateMachine +Metadata: + SamTransformTest: true diff --git a/tests/translator/input/state_machine_with_api_combination.yaml b/tests/translator/input/state_machine_with_api_combination.yaml new file mode 100644 index 000000000..abf4c003f --- /dev/null +++ b/tests/translator/input/state_machine_with_api_combination.yaml @@ -0,0 +1,76 @@ +Resources: + + # Create one API resource. This will be referred to by the State machine + ExistingRestApi: + Type: AWS::Serverless::Api + Properties: + StageName: Dev + + MyStateMachine: + Type: AWS::Serverless::StateMachine + Properties: + Definition: + Comment: A Hello World example of the Amazon States Language using Pass states + StartAt: Hello + States: + Hello: + Type: Pass + Result: Hello + Next: World + World: + Type: Pass + Result: World + End: true + Policies: + - Version: '2012-10-17' + Statement: + - Effect: Deny + Action: '*' + Resource: '*' + + Events: + GetApi: + Type: Api + Properties: + Path: /pathget + Method: get + RestApiId: + Ref: ExistingRestApi + + PostApi: + Type: Api + Properties: + Path: /pathpost + Method: post + +Outputs: + Region: + Description: Region + Value: + Ref: AWS::Region + Partition: + Description: Partition + Value: + Ref: AWS::Partition + MyStateMachineArn: + Description: ARN of the State Machine + Value: + Ref: MyStateMachine + MyImplicitApiRoleName: + Description: Name of the role created for the implicit Api method + Value: + Ref: MyStateMachinePostApiRole + MyImplicitApiRoleArn: + Description: ARN of the role created for the implicit Api method + Value: + Fn::GetAtt: MyStateMachinePostApiRole.Arn + MyExplicitApiRoleName: + Description: Name of the role created for the explicit Api method + Value: + Ref: MyStateMachineGetApiRole + MyExplicitApiRoleArn: + Description: ARN of the role created for the explicit Api method + Value: + Fn::GetAtt: MyStateMachineGetApiRole.Arn +Metadata: + SamTransformTest: true diff --git a/tests/translator/input/state_machine_with_api_single.yaml b/tests/translator/input/state_machine_with_api_single.yaml new file mode 100644 index 000000000..0fe28583e --- /dev/null +++ b/tests/translator/input/state_machine_with_api_single.yaml @@ -0,0 +1,41 @@ +Transform: AWS::Serverless-2016-10-31 +Resources: + MyApi: + Type: AWS::Serverless::Api + Properties: + StageName: Prod + HelloWorldFunction: + Type: AWS::Serverless::Function + Properties: + InlineCode: | + def handler(event, context): + print(event) + return "do nothing" + Handler: index.handler + Runtime: python3.8 + Post: + Type: AWS::Serverless::StateMachine + Properties: + Policies: + - arn:aws:iam::aws:policy/AWSLambda_FullAccess + Definition: + StartAt: One + States: + One: + Type: Task + Resource: !GetAtt HelloWorldFunction.Arn + End: true + Events: + PostEcho: + Type: Api + Properties: + RestApiId: !Ref MyApi + Path: /echo + Method: POST + UnescapeMappingTemplate: true + +Outputs: + ApiEndpoint: + Value: !Sub "https://${MyApi}.execute-api.${AWS::Region}.${AWS::URLSuffix}/Prod/echo" +Metadata: + SamTransformTest: true diff --git a/tests/translator/output/api_with_custom_domains_regional.json b/tests/translator/output/api_with_custom_domains_regional.json new file mode 100644 index 000000000..81b4c930b --- /dev/null +++ b/tests/translator/output/api_with_custom_domains_regional.json @@ -0,0 +1,254 @@ +{ + "Metadata": { + "SamTransformTest": true + }, + "Parameters": { + "HostedZoneId": { + "Type": "String" + }, + "MyRestRegionalDomainCert": { + "Type": "String" + }, + "MyRestRegionalDomainName": { + "Type": "String" + } + }, + "Resources": { + "ApiGatewayDomainName1a01391c0c": { + "Properties": { + "DomainName": { + "Ref": "MyRestRegionalDomainName" + }, + "EndpointConfiguration": { + "Types": [ + "REGIONAL" + ] + }, + "MutualTlsAuthentication": { + "TruststoreUri": "${mtlsuri}" + }, + "RegionalCertificateArn": { + "Ref": "MyRestRegionalDomainCert" + }, + "SecurityPolicy": "TLS_1_2" + }, + "Type": "AWS::ApiGateway::DomainName" + }, + "MyFunction": { + "Properties": { + "Code": { + "ZipFile": "exports.handler = async (event) => {\n const response = {\n statusCode: 200,\n body: JSON.stringify('Hello from Lambda!'),\n };\n return response;\n};\n" + }, + "Handler": "index.handler", + "Role": { + "Fn::GetAtt": [ + "MyFunctionRole", + "Arn" + ] + }, + "Runtime": "nodejs14.x", + "Tags": [ + { + "Key": "lambda:createdBy", + "Value": "SAM" + } + ] + }, + "Type": "AWS::Lambda::Function" + }, + "MyFunctionImplicitGetPermissionProd": { + "Properties": { + "Action": "lambda:InvokeFunction", + "FunctionName": { + "Ref": "MyFunction" + }, + "Principal": "apigateway.amazonaws.com", + "SourceArn": { + "Fn::Sub": [ + "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/get", + { + "__ApiId__": { + "Ref": "ServerlessRestApi" + }, + "__Stage__": "*" + } + ] + } + }, + "Type": "AWS::Lambda::Permission" + }, + "MyFunctionImplicitPostPermissionProd": { + "Properties": { + "Action": "lambda:InvokeFunction", + "FunctionName": { + "Ref": "MyFunction" + }, + "Principal": "apigateway.amazonaws.com", + "SourceArn": { + "Fn::Sub": [ + "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/POST/post", + { + "__ApiId__": { + "Ref": "ServerlessRestApi" + }, + "__Stage__": "*" + } + ] + } + }, + "Type": "AWS::Lambda::Permission" + }, + "MyFunctionRole": { + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "Tags": [ + { + "Key": "lambda:createdBy", + "Value": "SAM" + } + ] + }, + "Type": "AWS::IAM::Role" + }, + "RecordSetGroup1194dea82a": { + "Properties": { + "HostedZoneId": { + "Ref": "HostedZoneId" + }, + "RecordSets": [ + { + "AliasTarget": { + "DNSName": { + "Fn::GetAtt": [ + "ApiGatewayDomainName1a01391c0c", + "RegionalDomainName" + ] + }, + "HostedZoneId": { + "Fn::GetAtt": [ + "ApiGatewayDomainName1a01391c0c", + "RegionalHostedZoneId" + ] + } + }, + "Name": { + "Ref": "MyRestRegionalDomainName" + }, + "Type": "A" + } + ] + }, + "Type": "AWS::Route53::RecordSetGroup" + }, + "ServerlessRestApi": { + "Properties": { + "Body": { + "info": { + "title": { + "Ref": "AWS::StackName" + }, + "version": "1.0" + }, + "paths": { + "/get": { + "get": { + "responses": {}, + "x-amazon-apigateway-integration": { + "httpMethod": "POST", + "type": "aws_proxy", + "uri": { + "Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunction.Arn}/invocations" + } + } + } + }, + "/post": { + "post": { + "responses": {}, + "x-amazon-apigateway-integration": { + "httpMethod": "POST", + "type": "aws_proxy", + "uri": { + "Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunction.Arn}/invocations" + } + } + } + } + }, + "swagger": "2.0" + } + }, + "Type": "AWS::ApiGateway::RestApi" + }, + "ServerlessRestApiDeployment4697061386": { + "Properties": { + "Description": "RestApi deployment id: 4697061386a7e696fb8f30105a102cad3712f1a6", + "RestApiId": { + "Ref": "ServerlessRestApi" + }, + "StageName": "Stage" + }, + "Type": "AWS::ApiGateway::Deployment" + }, + "ServerlessRestApiProdStage": { + "Properties": { + "DeploymentId": { + "Ref": "ServerlessRestApiDeployment4697061386" + }, + "RestApiId": { + "Ref": "ServerlessRestApi" + }, + "StageName": "Prod" + }, + "Type": "AWS::ApiGateway::Stage" + }, + "ServerlessRestApigetBasePathMapping": { + "Properties": { + "BasePath": "get", + "DomainName": { + "Ref": "ApiGatewayDomainName1a01391c0c" + }, + "RestApiId": { + "Ref": "ServerlessRestApi" + }, + "Stage": { + "Ref": "ServerlessRestApiProdStage" + } + }, + "Type": "AWS::ApiGateway::BasePathMapping" + }, + "ServerlessRestApipostBasePathMapping": { + "Properties": { + "BasePath": "post", + "DomainName": { + "Ref": "ApiGatewayDomainName1a01391c0c" + }, + "RestApiId": { + "Ref": "ServerlessRestApi" + }, + "Stage": { + "Ref": "ServerlessRestApiProdStage" + } + }, + "Type": "AWS::ApiGateway::BasePathMapping" + } + } +} diff --git a/tests/translator/output/aws-cn/api_with_custom_domains_regional.json b/tests/translator/output/aws-cn/api_with_custom_domains_regional.json new file mode 100644 index 000000000..8594d7c91 --- /dev/null +++ b/tests/translator/output/aws-cn/api_with_custom_domains_regional.json @@ -0,0 +1,262 @@ +{ + "Metadata": { + "SamTransformTest": true + }, + "Parameters": { + "HostedZoneId": { + "Type": "String" + }, + "MyRestRegionalDomainCert": { + "Type": "String" + }, + "MyRestRegionalDomainName": { + "Type": "String" + } + }, + "Resources": { + "ApiGatewayDomainName1a01391c0c": { + "Properties": { + "DomainName": { + "Ref": "MyRestRegionalDomainName" + }, + "EndpointConfiguration": { + "Types": [ + "REGIONAL" + ] + }, + "MutualTlsAuthentication": { + "TruststoreUri": "${mtlsuri}" + }, + "RegionalCertificateArn": { + "Ref": "MyRestRegionalDomainCert" + }, + "SecurityPolicy": "TLS_1_2" + }, + "Type": "AWS::ApiGateway::DomainName" + }, + "MyFunction": { + "Properties": { + "Code": { + "ZipFile": "exports.handler = async (event) => {\n const response = {\n statusCode: 200,\n body: JSON.stringify('Hello from Lambda!'),\n };\n return response;\n};\n" + }, + "Handler": "index.handler", + "Role": { + "Fn::GetAtt": [ + "MyFunctionRole", + "Arn" + ] + }, + "Runtime": "nodejs14.x", + "Tags": [ + { + "Key": "lambda:createdBy", + "Value": "SAM" + } + ] + }, + "Type": "AWS::Lambda::Function" + }, + "MyFunctionImplicitGetPermissionProd": { + "Properties": { + "Action": "lambda:InvokeFunction", + "FunctionName": { + "Ref": "MyFunction" + }, + "Principal": "apigateway.amazonaws.com", + "SourceArn": { + "Fn::Sub": [ + "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/get", + { + "__ApiId__": { + "Ref": "ServerlessRestApi" + }, + "__Stage__": "*" + } + ] + } + }, + "Type": "AWS::Lambda::Permission" + }, + "MyFunctionImplicitPostPermissionProd": { + "Properties": { + "Action": "lambda:InvokeFunction", + "FunctionName": { + "Ref": "MyFunction" + }, + "Principal": "apigateway.amazonaws.com", + "SourceArn": { + "Fn::Sub": [ + "arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/POST/post", + { + "__ApiId__": { + "Ref": "ServerlessRestApi" + }, + "__Stage__": "*" + } + ] + } + }, + "Type": "AWS::Lambda::Permission" + }, + "MyFunctionRole": { + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + "arn:aws-cn:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "Tags": [ + { + "Key": "lambda:createdBy", + "Value": "SAM" + } + ] + }, + "Type": "AWS::IAM::Role" + }, + "RecordSetGroup1194dea82a": { + "Properties": { + "HostedZoneId": { + "Ref": "HostedZoneId" + }, + "RecordSets": [ + { + "AliasTarget": { + "DNSName": { + "Fn::GetAtt": [ + "ApiGatewayDomainName1a01391c0c", + "RegionalDomainName" + ] + }, + "HostedZoneId": { + "Fn::GetAtt": [ + "ApiGatewayDomainName1a01391c0c", + "RegionalHostedZoneId" + ] + } + }, + "Name": { + "Ref": "MyRestRegionalDomainName" + }, + "Type": "A" + } + ] + }, + "Type": "AWS::Route53::RecordSetGroup" + }, + "ServerlessRestApi": { + "Properties": { + "Body": { + "info": { + "title": { + "Ref": "AWS::StackName" + }, + "version": "1.0" + }, + "paths": { + "/get": { + "get": { + "responses": {}, + "x-amazon-apigateway-integration": { + "httpMethod": "POST", + "type": "aws_proxy", + "uri": { + "Fn::Sub": "arn:aws-cn:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunction.Arn}/invocations" + } + } + } + }, + "/post": { + "post": { + "responses": {}, + "x-amazon-apigateway-integration": { + "httpMethod": "POST", + "type": "aws_proxy", + "uri": { + "Fn::Sub": "arn:aws-cn:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunction.Arn}/invocations" + } + } + } + } + }, + "swagger": "2.0" + }, + "EndpointConfiguration": { + "Types": [ + "REGIONAL" + ] + }, + "Parameters": { + "endpointConfigurationTypes": "REGIONAL" + } + }, + "Type": "AWS::ApiGateway::RestApi" + }, + "ServerlessRestApiDeployment2b4b9de8a9": { + "Properties": { + "Description": "RestApi deployment id: 2b4b9de8a9906ddb175aeb81b23a6ce1694d4be7", + "RestApiId": { + "Ref": "ServerlessRestApi" + }, + "StageName": "Stage" + }, + "Type": "AWS::ApiGateway::Deployment" + }, + "ServerlessRestApiProdStage": { + "Properties": { + "DeploymentId": { + "Ref": "ServerlessRestApiDeployment2b4b9de8a9" + }, + "RestApiId": { + "Ref": "ServerlessRestApi" + }, + "StageName": "Prod" + }, + "Type": "AWS::ApiGateway::Stage" + }, + "ServerlessRestApigetBasePathMapping": { + "Properties": { + "BasePath": "get", + "DomainName": { + "Ref": "ApiGatewayDomainName1a01391c0c" + }, + "RestApiId": { + "Ref": "ServerlessRestApi" + }, + "Stage": { + "Ref": "ServerlessRestApiProdStage" + } + }, + "Type": "AWS::ApiGateway::BasePathMapping" + }, + "ServerlessRestApipostBasePathMapping": { + "Properties": { + "BasePath": "post", + "DomainName": { + "Ref": "ApiGatewayDomainName1a01391c0c" + }, + "RestApiId": { + "Ref": "ServerlessRestApi" + }, + "Stage": { + "Ref": "ServerlessRestApiProdStage" + } + }, + "Type": "AWS::ApiGateway::BasePathMapping" + } + } +} diff --git a/tests/translator/output/aws-cn/basic_state_machine_with_tags.json b/tests/translator/output/aws-cn/basic_state_machine_with_tags.json new file mode 100644 index 000000000..28052efe2 --- /dev/null +++ b/tests/translator/output/aws-cn/basic_state_machine_with_tags.json @@ -0,0 +1,119 @@ +{ + "Metadata": { + "SamTransformTest": true + }, + "Outputs": { + "MyStateMachineArn": { + "Description": "ARN of the state machine", + "Value": { + "Ref": "MyStateMachine" + } + } + }, + "Resources": { + "MyStateMachine": { + "Properties": { + "DefinitionString": { + "Fn::Join": [ + "\n", + [ + "{", + " \"Comment\": \"A Hello World example of the Amazon States Language using Pass states\",", + " \"StartAt\": \"Hello\",", + " \"States\": {", + " \"Hello\": {", + " \"Next\": \"World\",", + " \"Result\": \"Hello\",", + " \"Type\": \"Pass\"", + " },", + " \"World\": {", + " \"End\": true,", + " \"Result\": \"World\",", + " \"Type\": \"Pass\"", + " }", + " }", + "}" + ] + ] + }, + "RoleArn": { + "Fn::GetAtt": [ + "MyStateMachineRole", + "Arn" + ] + }, + "Tags": [ + { + "Key": "stateMachine:createdBy", + "Value": "SAM" + }, + { + "Key": "TagOne", + "Value": "ValueOne" + }, + { + "Key": "TagTwo", + "Value": "ValueTwo" + } + ], + "TracingConfiguration": { + "Enabled": true + } + }, + "Type": "AWS::StepFunctions::StateMachine" + }, + "MyStateMachineRole": { + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "states.amazonaws.com" + ] + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + "arn:aws-cn:iam::aws:policy/AWSXRayDaemonWriteAccess" + ], + "Policies": [ + { + "PolicyDocument": { + "Statement": [ + { + "Action": "*", + "Effect": "Deny", + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "MyStateMachineRolePolicy0" + } + ], + "Tags": [ + { + "Key": "stateMachine:createdBy", + "Value": "SAM" + }, + { + "Key": "TagOne", + "Value": "ValueOne" + }, + { + "Key": "TagTwo", + "Value": "ValueTwo" + } + ] + }, + "Type": "AWS::IAM::Role" + } + } +} diff --git a/tests/translator/output/aws-cn/state_machine_with_api_combination.json b/tests/translator/output/aws-cn/state_machine_with_api_combination.json new file mode 100644 index 000000000..13ca96d94 --- /dev/null +++ b/tests/translator/output/aws-cn/state_machine_with_api_combination.json @@ -0,0 +1,376 @@ +{ + "Metadata": { + "SamTransformTest": true + }, + "Outputs": { + "MyExplicitApiRoleArn": { + "Description": "ARN of the role created for the explicit Api method", + "Value": { + "Fn::GetAtt": "MyStateMachineGetApiRole.Arn" + } + }, + "MyExplicitApiRoleName": { + "Description": "Name of the role created for the explicit Api method", + "Value": { + "Ref": "MyStateMachineGetApiRole" + } + }, + "MyImplicitApiRoleArn": { + "Description": "ARN of the role created for the implicit Api method", + "Value": { + "Fn::GetAtt": "MyStateMachinePostApiRole.Arn" + } + }, + "MyImplicitApiRoleName": { + "Description": "Name of the role created for the implicit Api method", + "Value": { + "Ref": "MyStateMachinePostApiRole" + } + }, + "MyStateMachineArn": { + "Description": "ARN of the State Machine", + "Value": { + "Ref": "MyStateMachine" + } + }, + "Partition": { + "Description": "Partition", + "Value": { + "Ref": "AWS::Partition" + } + }, + "Region": { + "Description": "Region", + "Value": { + "Ref": "AWS::Region" + } + } + }, + "Resources": { + "ExistingRestApi": { + "Properties": { + "Body": { + "info": { + "title": { + "Ref": "AWS::StackName" + }, + "version": "1.0" + }, + "paths": { + "/pathget": { + "get": { + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Bad Request" + } + }, + "x-amazon-apigateway-integration": { + "credentials": { + "Fn::GetAtt": [ + "MyStateMachineGetApiRole", + "Arn" + ] + }, + "httpMethod": "POST", + "requestTemplates": { + "application/json": { + "Fn::Sub": "{\"input\": \"$util.escapeJavaScript($input.json('$'))\", \"stateMachineArn\": \"${MyStateMachine}\"}" + } + }, + "responses": { + "200": { + "statusCode": "200" + }, + "400": { + "statusCode": "400" + } + }, + "type": "aws", + "uri": { + "Fn::Sub": "arn:${AWS::Partition}:apigateway:${AWS::Region}:states:action/StartExecution" + } + } + } + } + }, + "swagger": "2.0" + }, + "EndpointConfiguration": { + "Types": [ + "REGIONAL" + ] + }, + "Parameters": { + "endpointConfigurationTypes": "REGIONAL" + } + }, + "Type": "AWS::ApiGateway::RestApi" + }, + "ExistingRestApiDeploymentefd42b7944": { + "Properties": { + "Description": "RestApi deployment id: efd42b7944cf8a0dfeb6547818e5ee11b117fa4d", + "RestApiId": { + "Ref": "ExistingRestApi" + }, + "StageName": "Stage" + }, + "Type": "AWS::ApiGateway::Deployment" + }, + "ExistingRestApiDevStage": { + "Properties": { + "DeploymentId": { + "Ref": "ExistingRestApiDeploymentefd42b7944" + }, + "RestApiId": { + "Ref": "ExistingRestApi" + }, + "StageName": "Dev" + }, + "Type": "AWS::ApiGateway::Stage" + }, + "MyStateMachine": { + "Properties": { + "DefinitionString": { + "Fn::Join": [ + "\n", + [ + "{", + " \"Comment\": \"A Hello World example of the Amazon States Language using Pass states\",", + " \"StartAt\": \"Hello\",", + " \"States\": {", + " \"Hello\": {", + " \"Next\": \"World\",", + " \"Result\": \"Hello\",", + " \"Type\": \"Pass\"", + " },", + " \"World\": {", + " \"End\": true,", + " \"Result\": \"World\",", + " \"Type\": \"Pass\"", + " }", + " }", + "}" + ] + ] + }, + "RoleArn": { + "Fn::GetAtt": [ + "MyStateMachineRole", + "Arn" + ] + }, + "Tags": [ + { + "Key": "stateMachine:createdBy", + "Value": "SAM" + } + ] + }, + "Type": "AWS::StepFunctions::StateMachine" + }, + "MyStateMachineGetApiRole": { + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "apigateway.amazonaws.com" + ] + } + } + ], + "Version": "2012-10-17" + }, + "Policies": [ + { + "PolicyDocument": { + "Statement": [ + { + "Action": "states:StartExecution", + "Effect": "Allow", + "Resource": { + "Ref": "MyStateMachine" + } + } + ] + }, + "PolicyName": "MyStateMachineGetApiRoleStartExecutionPolicy" + } + ] + }, + "Type": "AWS::IAM::Role" + }, + "MyStateMachinePostApiRole": { + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "apigateway.amazonaws.com" + ] + } + } + ], + "Version": "2012-10-17" + }, + "Policies": [ + { + "PolicyDocument": { + "Statement": [ + { + "Action": "states:StartExecution", + "Effect": "Allow", + "Resource": { + "Ref": "MyStateMachine" + } + } + ] + }, + "PolicyName": "MyStateMachinePostApiRoleStartExecutionPolicy" + } + ] + }, + "Type": "AWS::IAM::Role" + }, + "MyStateMachineRole": { + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "states.amazonaws.com" + ] + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [], + "Policies": [ + { + "PolicyDocument": { + "Statement": [ + { + "Action": "*", + "Effect": "Deny", + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "MyStateMachineRolePolicy0" + } + ], + "Tags": [ + { + "Key": "stateMachine:createdBy", + "Value": "SAM" + } + ] + }, + "Type": "AWS::IAM::Role" + }, + "ServerlessRestApi": { + "Properties": { + "Body": { + "info": { + "title": { + "Ref": "AWS::StackName" + }, + "version": "1.0" + }, + "paths": { + "/pathpost": { + "post": { + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Bad Request" + } + }, + "x-amazon-apigateway-integration": { + "credentials": { + "Fn::GetAtt": [ + "MyStateMachinePostApiRole", + "Arn" + ] + }, + "httpMethod": "POST", + "requestTemplates": { + "application/json": { + "Fn::Sub": "{\"input\": \"$util.escapeJavaScript($input.json('$'))\", \"stateMachineArn\": \"${MyStateMachine}\"}" + } + }, + "responses": { + "200": { + "statusCode": "200" + }, + "400": { + "statusCode": "400" + } + }, + "type": "aws", + "uri": { + "Fn::Sub": "arn:${AWS::Partition}:apigateway:${AWS::Region}:states:action/StartExecution" + } + } + } + } + }, + "swagger": "2.0" + }, + "EndpointConfiguration": { + "Types": [ + "REGIONAL" + ] + }, + "Parameters": { + "endpointConfigurationTypes": "REGIONAL" + } + }, + "Type": "AWS::ApiGateway::RestApi" + }, + "ServerlessRestApiDeployment5390046d30": { + "Properties": { + "Description": "RestApi deployment id: 5390046d30af30202ffeefe3944e76579b71af99", + "RestApiId": { + "Ref": "ServerlessRestApi" + }, + "StageName": "Stage" + }, + "Type": "AWS::ApiGateway::Deployment" + }, + "ServerlessRestApiProdStage": { + "Properties": { + "DeploymentId": { + "Ref": "ServerlessRestApiDeployment5390046d30" + }, + "RestApiId": { + "Ref": "ServerlessRestApi" + }, + "StageName": "Prod" + }, + "Type": "AWS::ApiGateway::Stage" + } + } +} diff --git a/tests/translator/output/aws-cn/state_machine_with_api_single.json b/tests/translator/output/aws-cn/state_machine_with_api_single.json new file mode 100644 index 000000000..706c4eca5 --- /dev/null +++ b/tests/translator/output/aws-cn/state_machine_with_api_single.json @@ -0,0 +1,259 @@ +{ + "Metadata": { + "SamTransformTest": true + }, + "Outputs": { + "ApiEndpoint": { + "Value": { + "Fn::Sub": "https://${MyApi}.execute-api.${AWS::Region}.${AWS::URLSuffix}/Prod/echo" + } + } + }, + "Resources": { + "HelloWorldFunction": { + "Properties": { + "Code": { + "ZipFile": "def handler(event, context):\n print(event)\n return \"do nothing\"\n" + }, + "Handler": "index.handler", + "Role": { + "Fn::GetAtt": [ + "HelloWorldFunctionRole", + "Arn" + ] + }, + "Runtime": "python3.8", + "Tags": [ + { + "Key": "lambda:createdBy", + "Value": "SAM" + } + ] + }, + "Type": "AWS::Lambda::Function" + }, + "HelloWorldFunctionRole": { + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + "arn:aws-cn:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "Tags": [ + { + "Key": "lambda:createdBy", + "Value": "SAM" + } + ] + }, + "Type": "AWS::IAM::Role" + }, + "MyApi": { + "Properties": { + "Body": { + "info": { + "title": { + "Ref": "AWS::StackName" + }, + "version": "1.0" + }, + "paths": { + "/echo": { + "post": { + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Bad Request" + } + }, + "x-amazon-apigateway-integration": { + "credentials": { + "Fn::GetAtt": [ + "PostPostEchoRole", + "Arn" + ] + }, + "httpMethod": "POST", + "requestTemplates": { + "application/json": { + "Fn::Sub": "{\"input\": \"$util.escapeJavaScript($input.json('$')).replaceAll(\"\\\\'\",\"'\")\", \"stateMachineArn\": \"${Post}\"}" + } + }, + "responses": { + "200": { + "statusCode": "200" + }, + "400": { + "statusCode": "400" + } + }, + "type": "aws", + "uri": { + "Fn::Sub": "arn:${AWS::Partition}:apigateway:${AWS::Region}:states:action/StartExecution" + } + } + } + } + }, + "swagger": "2.0" + }, + "EndpointConfiguration": { + "Types": [ + "REGIONAL" + ] + }, + "Parameters": { + "endpointConfigurationTypes": "REGIONAL" + } + }, + "Type": "AWS::ApiGateway::RestApi" + }, + "MyApiDeployment5866b9014d": { + "Properties": { + "Description": "RestApi deployment id: 5866b9014d5a1c815da161bacc3b15b4a19f95ef", + "RestApiId": { + "Ref": "MyApi" + }, + "StageName": "Stage" + }, + "Type": "AWS::ApiGateway::Deployment" + }, + "MyApiProdStage": { + "Properties": { + "DeploymentId": { + "Ref": "MyApiDeployment5866b9014d" + }, + "RestApiId": { + "Ref": "MyApi" + }, + "StageName": "Prod" + }, + "Type": "AWS::ApiGateway::Stage" + }, + "Post": { + "Properties": { + "DefinitionString": { + "Fn::Join": [ + "\n", + [ + "{", + " \"StartAt\": \"One\",", + " \"States\": {", + " \"One\": {", + " \"End\": true,", + " \"Resource\": \"${definition_substitution_1}\",", + " \"Type\": \"Task\"", + " }", + " }", + "}" + ] + ] + }, + "DefinitionSubstitutions": { + "definition_substitution_1": { + "Fn::GetAtt": [ + "HelloWorldFunction", + "Arn" + ] + } + }, + "RoleArn": { + "Fn::GetAtt": [ + "PostRole", + "Arn" + ] + }, + "Tags": [ + { + "Key": "stateMachine:createdBy", + "Value": "SAM" + } + ] + }, + "Type": "AWS::StepFunctions::StateMachine" + }, + "PostPostEchoRole": { + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "apigateway.amazonaws.com" + ] + } + } + ], + "Version": "2012-10-17" + }, + "Policies": [ + { + "PolicyDocument": { + "Statement": [ + { + "Action": "states:StartExecution", + "Effect": "Allow", + "Resource": { + "Ref": "Post" + } + } + ] + }, + "PolicyName": "PostPostEchoRoleStartExecutionPolicy" + } + ] + }, + "Type": "AWS::IAM::Role" + }, + "PostRole": { + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "states.amazonaws.com" + ] + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + "arn:aws:iam::aws:policy/AWSLambda_FullAccess" + ], + "Tags": [ + { + "Key": "stateMachine:createdBy", + "Value": "SAM" + } + ] + }, + "Type": "AWS::IAM::Role" + } + } +} diff --git a/tests/translator/output/aws-us-gov/api_with_custom_domains_regional.json b/tests/translator/output/aws-us-gov/api_with_custom_domains_regional.json new file mode 100644 index 000000000..ffc00bff5 --- /dev/null +++ b/tests/translator/output/aws-us-gov/api_with_custom_domains_regional.json @@ -0,0 +1,262 @@ +{ + "Metadata": { + "SamTransformTest": true + }, + "Parameters": { + "HostedZoneId": { + "Type": "String" + }, + "MyRestRegionalDomainCert": { + "Type": "String" + }, + "MyRestRegionalDomainName": { + "Type": "String" + } + }, + "Resources": { + "ApiGatewayDomainName1a01391c0c": { + "Properties": { + "DomainName": { + "Ref": "MyRestRegionalDomainName" + }, + "EndpointConfiguration": { + "Types": [ + "REGIONAL" + ] + }, + "MutualTlsAuthentication": { + "TruststoreUri": "${mtlsuri}" + }, + "RegionalCertificateArn": { + "Ref": "MyRestRegionalDomainCert" + }, + "SecurityPolicy": "TLS_1_2" + }, + "Type": "AWS::ApiGateway::DomainName" + }, + "MyFunction": { + "Properties": { + "Code": { + "ZipFile": "exports.handler = async (event) => {\n const response = {\n statusCode: 200,\n body: JSON.stringify('Hello from Lambda!'),\n };\n return response;\n};\n" + }, + "Handler": "index.handler", + "Role": { + "Fn::GetAtt": [ + "MyFunctionRole", + "Arn" + ] + }, + "Runtime": "nodejs14.x", + "Tags": [ + { + "Key": "lambda:createdBy", + "Value": "SAM" + } + ] + }, + "Type": "AWS::Lambda::Function" + }, + "MyFunctionImplicitGetPermissionProd": { + "Properties": { + "Action": "lambda:InvokeFunction", + "FunctionName": { + "Ref": "MyFunction" + }, + "Principal": "apigateway.amazonaws.com", + "SourceArn": { + "Fn::Sub": [ + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/get", + { + "__ApiId__": { + "Ref": "ServerlessRestApi" + }, + "__Stage__": "*" + } + ] + } + }, + "Type": "AWS::Lambda::Permission" + }, + "MyFunctionImplicitPostPermissionProd": { + "Properties": { + "Action": "lambda:InvokeFunction", + "FunctionName": { + "Ref": "MyFunction" + }, + "Principal": "apigateway.amazonaws.com", + "SourceArn": { + "Fn::Sub": [ + "arn:aws-us-gov:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/POST/post", + { + "__ApiId__": { + "Ref": "ServerlessRestApi" + }, + "__Stage__": "*" + } + ] + } + }, + "Type": "AWS::Lambda::Permission" + }, + "MyFunctionRole": { + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + "arn:aws-us-gov:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "Tags": [ + { + "Key": "lambda:createdBy", + "Value": "SAM" + } + ] + }, + "Type": "AWS::IAM::Role" + }, + "RecordSetGroup1194dea82a": { + "Properties": { + "HostedZoneId": { + "Ref": "HostedZoneId" + }, + "RecordSets": [ + { + "AliasTarget": { + "DNSName": { + "Fn::GetAtt": [ + "ApiGatewayDomainName1a01391c0c", + "RegionalDomainName" + ] + }, + "HostedZoneId": { + "Fn::GetAtt": [ + "ApiGatewayDomainName1a01391c0c", + "RegionalHostedZoneId" + ] + } + }, + "Name": { + "Ref": "MyRestRegionalDomainName" + }, + "Type": "A" + } + ] + }, + "Type": "AWS::Route53::RecordSetGroup" + }, + "ServerlessRestApi": { + "Properties": { + "Body": { + "info": { + "title": { + "Ref": "AWS::StackName" + }, + "version": "1.0" + }, + "paths": { + "/get": { + "get": { + "responses": {}, + "x-amazon-apigateway-integration": { + "httpMethod": "POST", + "type": "aws_proxy", + "uri": { + "Fn::Sub": "arn:aws-us-gov:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunction.Arn}/invocations" + } + } + } + }, + "/post": { + "post": { + "responses": {}, + "x-amazon-apigateway-integration": { + "httpMethod": "POST", + "type": "aws_proxy", + "uri": { + "Fn::Sub": "arn:aws-us-gov:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunction.Arn}/invocations" + } + } + } + } + }, + "swagger": "2.0" + }, + "EndpointConfiguration": { + "Types": [ + "REGIONAL" + ] + }, + "Parameters": { + "endpointConfigurationTypes": "REGIONAL" + } + }, + "Type": "AWS::ApiGateway::RestApi" + }, + "ServerlessRestApiDeployment4981e855f4": { + "Properties": { + "Description": "RestApi deployment id: 4981e855f450ed8c4ca07a733c3bade18abf9592", + "RestApiId": { + "Ref": "ServerlessRestApi" + }, + "StageName": "Stage" + }, + "Type": "AWS::ApiGateway::Deployment" + }, + "ServerlessRestApiProdStage": { + "Properties": { + "DeploymentId": { + "Ref": "ServerlessRestApiDeployment4981e855f4" + }, + "RestApiId": { + "Ref": "ServerlessRestApi" + }, + "StageName": "Prod" + }, + "Type": "AWS::ApiGateway::Stage" + }, + "ServerlessRestApigetBasePathMapping": { + "Properties": { + "BasePath": "get", + "DomainName": { + "Ref": "ApiGatewayDomainName1a01391c0c" + }, + "RestApiId": { + "Ref": "ServerlessRestApi" + }, + "Stage": { + "Ref": "ServerlessRestApiProdStage" + } + }, + "Type": "AWS::ApiGateway::BasePathMapping" + }, + "ServerlessRestApipostBasePathMapping": { + "Properties": { + "BasePath": "post", + "DomainName": { + "Ref": "ApiGatewayDomainName1a01391c0c" + }, + "RestApiId": { + "Ref": "ServerlessRestApi" + }, + "Stage": { + "Ref": "ServerlessRestApiProdStage" + } + }, + "Type": "AWS::ApiGateway::BasePathMapping" + } + } +} diff --git a/tests/translator/output/aws-us-gov/basic_state_machine_with_tags.json b/tests/translator/output/aws-us-gov/basic_state_machine_with_tags.json new file mode 100644 index 000000000..858c3e47e --- /dev/null +++ b/tests/translator/output/aws-us-gov/basic_state_machine_with_tags.json @@ -0,0 +1,119 @@ +{ + "Metadata": { + "SamTransformTest": true + }, + "Outputs": { + "MyStateMachineArn": { + "Description": "ARN of the state machine", + "Value": { + "Ref": "MyStateMachine" + } + } + }, + "Resources": { + "MyStateMachine": { + "Properties": { + "DefinitionString": { + "Fn::Join": [ + "\n", + [ + "{", + " \"Comment\": \"A Hello World example of the Amazon States Language using Pass states\",", + " \"StartAt\": \"Hello\",", + " \"States\": {", + " \"Hello\": {", + " \"Next\": \"World\",", + " \"Result\": \"Hello\",", + " \"Type\": \"Pass\"", + " },", + " \"World\": {", + " \"End\": true,", + " \"Result\": \"World\",", + " \"Type\": \"Pass\"", + " }", + " }", + "}" + ] + ] + }, + "RoleArn": { + "Fn::GetAtt": [ + "MyStateMachineRole", + "Arn" + ] + }, + "Tags": [ + { + "Key": "stateMachine:createdBy", + "Value": "SAM" + }, + { + "Key": "TagOne", + "Value": "ValueOne" + }, + { + "Key": "TagTwo", + "Value": "ValueTwo" + } + ], + "TracingConfiguration": { + "Enabled": true + } + }, + "Type": "AWS::StepFunctions::StateMachine" + }, + "MyStateMachineRole": { + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "states.amazonaws.com" + ] + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + "arn:aws-us-gov:iam::aws:policy/AWSXRayDaemonWriteAccess" + ], + "Policies": [ + { + "PolicyDocument": { + "Statement": [ + { + "Action": "*", + "Effect": "Deny", + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "MyStateMachineRolePolicy0" + } + ], + "Tags": [ + { + "Key": "stateMachine:createdBy", + "Value": "SAM" + }, + { + "Key": "TagOne", + "Value": "ValueOne" + }, + { + "Key": "TagTwo", + "Value": "ValueTwo" + } + ] + }, + "Type": "AWS::IAM::Role" + } + } +} diff --git a/tests/translator/output/aws-us-gov/state_machine_with_api_combination.json b/tests/translator/output/aws-us-gov/state_machine_with_api_combination.json new file mode 100644 index 000000000..13ca96d94 --- /dev/null +++ b/tests/translator/output/aws-us-gov/state_machine_with_api_combination.json @@ -0,0 +1,376 @@ +{ + "Metadata": { + "SamTransformTest": true + }, + "Outputs": { + "MyExplicitApiRoleArn": { + "Description": "ARN of the role created for the explicit Api method", + "Value": { + "Fn::GetAtt": "MyStateMachineGetApiRole.Arn" + } + }, + "MyExplicitApiRoleName": { + "Description": "Name of the role created for the explicit Api method", + "Value": { + "Ref": "MyStateMachineGetApiRole" + } + }, + "MyImplicitApiRoleArn": { + "Description": "ARN of the role created for the implicit Api method", + "Value": { + "Fn::GetAtt": "MyStateMachinePostApiRole.Arn" + } + }, + "MyImplicitApiRoleName": { + "Description": "Name of the role created for the implicit Api method", + "Value": { + "Ref": "MyStateMachinePostApiRole" + } + }, + "MyStateMachineArn": { + "Description": "ARN of the State Machine", + "Value": { + "Ref": "MyStateMachine" + } + }, + "Partition": { + "Description": "Partition", + "Value": { + "Ref": "AWS::Partition" + } + }, + "Region": { + "Description": "Region", + "Value": { + "Ref": "AWS::Region" + } + } + }, + "Resources": { + "ExistingRestApi": { + "Properties": { + "Body": { + "info": { + "title": { + "Ref": "AWS::StackName" + }, + "version": "1.0" + }, + "paths": { + "/pathget": { + "get": { + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Bad Request" + } + }, + "x-amazon-apigateway-integration": { + "credentials": { + "Fn::GetAtt": [ + "MyStateMachineGetApiRole", + "Arn" + ] + }, + "httpMethod": "POST", + "requestTemplates": { + "application/json": { + "Fn::Sub": "{\"input\": \"$util.escapeJavaScript($input.json('$'))\", \"stateMachineArn\": \"${MyStateMachine}\"}" + } + }, + "responses": { + "200": { + "statusCode": "200" + }, + "400": { + "statusCode": "400" + } + }, + "type": "aws", + "uri": { + "Fn::Sub": "arn:${AWS::Partition}:apigateway:${AWS::Region}:states:action/StartExecution" + } + } + } + } + }, + "swagger": "2.0" + }, + "EndpointConfiguration": { + "Types": [ + "REGIONAL" + ] + }, + "Parameters": { + "endpointConfigurationTypes": "REGIONAL" + } + }, + "Type": "AWS::ApiGateway::RestApi" + }, + "ExistingRestApiDeploymentefd42b7944": { + "Properties": { + "Description": "RestApi deployment id: efd42b7944cf8a0dfeb6547818e5ee11b117fa4d", + "RestApiId": { + "Ref": "ExistingRestApi" + }, + "StageName": "Stage" + }, + "Type": "AWS::ApiGateway::Deployment" + }, + "ExistingRestApiDevStage": { + "Properties": { + "DeploymentId": { + "Ref": "ExistingRestApiDeploymentefd42b7944" + }, + "RestApiId": { + "Ref": "ExistingRestApi" + }, + "StageName": "Dev" + }, + "Type": "AWS::ApiGateway::Stage" + }, + "MyStateMachine": { + "Properties": { + "DefinitionString": { + "Fn::Join": [ + "\n", + [ + "{", + " \"Comment\": \"A Hello World example of the Amazon States Language using Pass states\",", + " \"StartAt\": \"Hello\",", + " \"States\": {", + " \"Hello\": {", + " \"Next\": \"World\",", + " \"Result\": \"Hello\",", + " \"Type\": \"Pass\"", + " },", + " \"World\": {", + " \"End\": true,", + " \"Result\": \"World\",", + " \"Type\": \"Pass\"", + " }", + " }", + "}" + ] + ] + }, + "RoleArn": { + "Fn::GetAtt": [ + "MyStateMachineRole", + "Arn" + ] + }, + "Tags": [ + { + "Key": "stateMachine:createdBy", + "Value": "SAM" + } + ] + }, + "Type": "AWS::StepFunctions::StateMachine" + }, + "MyStateMachineGetApiRole": { + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "apigateway.amazonaws.com" + ] + } + } + ], + "Version": "2012-10-17" + }, + "Policies": [ + { + "PolicyDocument": { + "Statement": [ + { + "Action": "states:StartExecution", + "Effect": "Allow", + "Resource": { + "Ref": "MyStateMachine" + } + } + ] + }, + "PolicyName": "MyStateMachineGetApiRoleStartExecutionPolicy" + } + ] + }, + "Type": "AWS::IAM::Role" + }, + "MyStateMachinePostApiRole": { + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "apigateway.amazonaws.com" + ] + } + } + ], + "Version": "2012-10-17" + }, + "Policies": [ + { + "PolicyDocument": { + "Statement": [ + { + "Action": "states:StartExecution", + "Effect": "Allow", + "Resource": { + "Ref": "MyStateMachine" + } + } + ] + }, + "PolicyName": "MyStateMachinePostApiRoleStartExecutionPolicy" + } + ] + }, + "Type": "AWS::IAM::Role" + }, + "MyStateMachineRole": { + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "states.amazonaws.com" + ] + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [], + "Policies": [ + { + "PolicyDocument": { + "Statement": [ + { + "Action": "*", + "Effect": "Deny", + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "MyStateMachineRolePolicy0" + } + ], + "Tags": [ + { + "Key": "stateMachine:createdBy", + "Value": "SAM" + } + ] + }, + "Type": "AWS::IAM::Role" + }, + "ServerlessRestApi": { + "Properties": { + "Body": { + "info": { + "title": { + "Ref": "AWS::StackName" + }, + "version": "1.0" + }, + "paths": { + "/pathpost": { + "post": { + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Bad Request" + } + }, + "x-amazon-apigateway-integration": { + "credentials": { + "Fn::GetAtt": [ + "MyStateMachinePostApiRole", + "Arn" + ] + }, + "httpMethod": "POST", + "requestTemplates": { + "application/json": { + "Fn::Sub": "{\"input\": \"$util.escapeJavaScript($input.json('$'))\", \"stateMachineArn\": \"${MyStateMachine}\"}" + } + }, + "responses": { + "200": { + "statusCode": "200" + }, + "400": { + "statusCode": "400" + } + }, + "type": "aws", + "uri": { + "Fn::Sub": "arn:${AWS::Partition}:apigateway:${AWS::Region}:states:action/StartExecution" + } + } + } + } + }, + "swagger": "2.0" + }, + "EndpointConfiguration": { + "Types": [ + "REGIONAL" + ] + }, + "Parameters": { + "endpointConfigurationTypes": "REGIONAL" + } + }, + "Type": "AWS::ApiGateway::RestApi" + }, + "ServerlessRestApiDeployment5390046d30": { + "Properties": { + "Description": "RestApi deployment id: 5390046d30af30202ffeefe3944e76579b71af99", + "RestApiId": { + "Ref": "ServerlessRestApi" + }, + "StageName": "Stage" + }, + "Type": "AWS::ApiGateway::Deployment" + }, + "ServerlessRestApiProdStage": { + "Properties": { + "DeploymentId": { + "Ref": "ServerlessRestApiDeployment5390046d30" + }, + "RestApiId": { + "Ref": "ServerlessRestApi" + }, + "StageName": "Prod" + }, + "Type": "AWS::ApiGateway::Stage" + } + } +} diff --git a/tests/translator/output/aws-us-gov/state_machine_with_api_single.json b/tests/translator/output/aws-us-gov/state_machine_with_api_single.json new file mode 100644 index 000000000..5b0d5b3d9 --- /dev/null +++ b/tests/translator/output/aws-us-gov/state_machine_with_api_single.json @@ -0,0 +1,259 @@ +{ + "Metadata": { + "SamTransformTest": true + }, + "Outputs": { + "ApiEndpoint": { + "Value": { + "Fn::Sub": "https://${MyApi}.execute-api.${AWS::Region}.${AWS::URLSuffix}/Prod/echo" + } + } + }, + "Resources": { + "HelloWorldFunction": { + "Properties": { + "Code": { + "ZipFile": "def handler(event, context):\n print(event)\n return \"do nothing\"\n" + }, + "Handler": "index.handler", + "Role": { + "Fn::GetAtt": [ + "HelloWorldFunctionRole", + "Arn" + ] + }, + "Runtime": "python3.8", + "Tags": [ + { + "Key": "lambda:createdBy", + "Value": "SAM" + } + ] + }, + "Type": "AWS::Lambda::Function" + }, + "HelloWorldFunctionRole": { + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + "arn:aws-us-gov:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "Tags": [ + { + "Key": "lambda:createdBy", + "Value": "SAM" + } + ] + }, + "Type": "AWS::IAM::Role" + }, + "MyApi": { + "Properties": { + "Body": { + "info": { + "title": { + "Ref": "AWS::StackName" + }, + "version": "1.0" + }, + "paths": { + "/echo": { + "post": { + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Bad Request" + } + }, + "x-amazon-apigateway-integration": { + "credentials": { + "Fn::GetAtt": [ + "PostPostEchoRole", + "Arn" + ] + }, + "httpMethod": "POST", + "requestTemplates": { + "application/json": { + "Fn::Sub": "{\"input\": \"$util.escapeJavaScript($input.json('$')).replaceAll(\"\\\\'\",\"'\")\", \"stateMachineArn\": \"${Post}\"}" + } + }, + "responses": { + "200": { + "statusCode": "200" + }, + "400": { + "statusCode": "400" + } + }, + "type": "aws", + "uri": { + "Fn::Sub": "arn:${AWS::Partition}:apigateway:${AWS::Region}:states:action/StartExecution" + } + } + } + } + }, + "swagger": "2.0" + }, + "EndpointConfiguration": { + "Types": [ + "REGIONAL" + ] + }, + "Parameters": { + "endpointConfigurationTypes": "REGIONAL" + } + }, + "Type": "AWS::ApiGateway::RestApi" + }, + "MyApiDeployment5866b9014d": { + "Properties": { + "Description": "RestApi deployment id: 5866b9014d5a1c815da161bacc3b15b4a19f95ef", + "RestApiId": { + "Ref": "MyApi" + }, + "StageName": "Stage" + }, + "Type": "AWS::ApiGateway::Deployment" + }, + "MyApiProdStage": { + "Properties": { + "DeploymentId": { + "Ref": "MyApiDeployment5866b9014d" + }, + "RestApiId": { + "Ref": "MyApi" + }, + "StageName": "Prod" + }, + "Type": "AWS::ApiGateway::Stage" + }, + "Post": { + "Properties": { + "DefinitionString": { + "Fn::Join": [ + "\n", + [ + "{", + " \"StartAt\": \"One\",", + " \"States\": {", + " \"One\": {", + " \"End\": true,", + " \"Resource\": \"${definition_substitution_1}\",", + " \"Type\": \"Task\"", + " }", + " }", + "}" + ] + ] + }, + "DefinitionSubstitutions": { + "definition_substitution_1": { + "Fn::GetAtt": [ + "HelloWorldFunction", + "Arn" + ] + } + }, + "RoleArn": { + "Fn::GetAtt": [ + "PostRole", + "Arn" + ] + }, + "Tags": [ + { + "Key": "stateMachine:createdBy", + "Value": "SAM" + } + ] + }, + "Type": "AWS::StepFunctions::StateMachine" + }, + "PostPostEchoRole": { + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "apigateway.amazonaws.com" + ] + } + } + ], + "Version": "2012-10-17" + }, + "Policies": [ + { + "PolicyDocument": { + "Statement": [ + { + "Action": "states:StartExecution", + "Effect": "Allow", + "Resource": { + "Ref": "Post" + } + } + ] + }, + "PolicyName": "PostPostEchoRoleStartExecutionPolicy" + } + ] + }, + "Type": "AWS::IAM::Role" + }, + "PostRole": { + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "states.amazonaws.com" + ] + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + "arn:aws:iam::aws:policy/AWSLambda_FullAccess" + ], + "Tags": [ + { + "Key": "stateMachine:createdBy", + "Value": "SAM" + } + ] + }, + "Type": "AWS::IAM::Role" + } + } +} diff --git a/tests/translator/output/basic_state_machine_with_tags.json b/tests/translator/output/basic_state_machine_with_tags.json new file mode 100644 index 000000000..e2f78afde --- /dev/null +++ b/tests/translator/output/basic_state_machine_with_tags.json @@ -0,0 +1,119 @@ +{ + "Metadata": { + "SamTransformTest": true + }, + "Outputs": { + "MyStateMachineArn": { + "Description": "ARN of the state machine", + "Value": { + "Ref": "MyStateMachine" + } + } + }, + "Resources": { + "MyStateMachine": { + "Properties": { + "DefinitionString": { + "Fn::Join": [ + "\n", + [ + "{", + " \"Comment\": \"A Hello World example of the Amazon States Language using Pass states\",", + " \"StartAt\": \"Hello\",", + " \"States\": {", + " \"Hello\": {", + " \"Next\": \"World\",", + " \"Result\": \"Hello\",", + " \"Type\": \"Pass\"", + " },", + " \"World\": {", + " \"End\": true,", + " \"Result\": \"World\",", + " \"Type\": \"Pass\"", + " }", + " }", + "}" + ] + ] + }, + "RoleArn": { + "Fn::GetAtt": [ + "MyStateMachineRole", + "Arn" + ] + }, + "Tags": [ + { + "Key": "stateMachine:createdBy", + "Value": "SAM" + }, + { + "Key": "TagOne", + "Value": "ValueOne" + }, + { + "Key": "TagTwo", + "Value": "ValueTwo" + } + ], + "TracingConfiguration": { + "Enabled": true + } + }, + "Type": "AWS::StepFunctions::StateMachine" + }, + "MyStateMachineRole": { + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "states.amazonaws.com" + ] + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + "arn:aws:iam::aws:policy/AWSXrayWriteOnlyAccess" + ], + "Policies": [ + { + "PolicyDocument": { + "Statement": [ + { + "Action": "*", + "Effect": "Deny", + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "MyStateMachineRolePolicy0" + } + ], + "Tags": [ + { + "Key": "stateMachine:createdBy", + "Value": "SAM" + }, + { + "Key": "TagOne", + "Value": "ValueOne" + }, + { + "Key": "TagTwo", + "Value": "ValueTwo" + } + ] + }, + "Type": "AWS::IAM::Role" + } + } +} diff --git a/tests/translator/output/state_machine_with_api_combination.json b/tests/translator/output/state_machine_with_api_combination.json new file mode 100644 index 000000000..4473ee3cf --- /dev/null +++ b/tests/translator/output/state_machine_with_api_combination.json @@ -0,0 +1,360 @@ +{ + "Metadata": { + "SamTransformTest": true + }, + "Outputs": { + "MyExplicitApiRoleArn": { + "Description": "ARN of the role created for the explicit Api method", + "Value": { + "Fn::GetAtt": "MyStateMachineGetApiRole.Arn" + } + }, + "MyExplicitApiRoleName": { + "Description": "Name of the role created for the explicit Api method", + "Value": { + "Ref": "MyStateMachineGetApiRole" + } + }, + "MyImplicitApiRoleArn": { + "Description": "ARN of the role created for the implicit Api method", + "Value": { + "Fn::GetAtt": "MyStateMachinePostApiRole.Arn" + } + }, + "MyImplicitApiRoleName": { + "Description": "Name of the role created for the implicit Api method", + "Value": { + "Ref": "MyStateMachinePostApiRole" + } + }, + "MyStateMachineArn": { + "Description": "ARN of the State Machine", + "Value": { + "Ref": "MyStateMachine" + } + }, + "Partition": { + "Description": "Partition", + "Value": { + "Ref": "AWS::Partition" + } + }, + "Region": { + "Description": "Region", + "Value": { + "Ref": "AWS::Region" + } + } + }, + "Resources": { + "ExistingRestApi": { + "Properties": { + "Body": { + "info": { + "title": { + "Ref": "AWS::StackName" + }, + "version": "1.0" + }, + "paths": { + "/pathget": { + "get": { + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Bad Request" + } + }, + "x-amazon-apigateway-integration": { + "credentials": { + "Fn::GetAtt": [ + "MyStateMachineGetApiRole", + "Arn" + ] + }, + "httpMethod": "POST", + "requestTemplates": { + "application/json": { + "Fn::Sub": "{\"input\": \"$util.escapeJavaScript($input.json('$'))\", \"stateMachineArn\": \"${MyStateMachine}\"}" + } + }, + "responses": { + "200": { + "statusCode": "200" + }, + "400": { + "statusCode": "400" + } + }, + "type": "aws", + "uri": { + "Fn::Sub": "arn:${AWS::Partition}:apigateway:${AWS::Region}:states:action/StartExecution" + } + } + } + } + }, + "swagger": "2.0" + } + }, + "Type": "AWS::ApiGateway::RestApi" + }, + "ExistingRestApiDeploymentefd42b7944": { + "Properties": { + "Description": "RestApi deployment id: efd42b7944cf8a0dfeb6547818e5ee11b117fa4d", + "RestApiId": { + "Ref": "ExistingRestApi" + }, + "StageName": "Stage" + }, + "Type": "AWS::ApiGateway::Deployment" + }, + "ExistingRestApiDevStage": { + "Properties": { + "DeploymentId": { + "Ref": "ExistingRestApiDeploymentefd42b7944" + }, + "RestApiId": { + "Ref": "ExistingRestApi" + }, + "StageName": "Dev" + }, + "Type": "AWS::ApiGateway::Stage" + }, + "MyStateMachine": { + "Properties": { + "DefinitionString": { + "Fn::Join": [ + "\n", + [ + "{", + " \"Comment\": \"A Hello World example of the Amazon States Language using Pass states\",", + " \"StartAt\": \"Hello\",", + " \"States\": {", + " \"Hello\": {", + " \"Next\": \"World\",", + " \"Result\": \"Hello\",", + " \"Type\": \"Pass\"", + " },", + " \"World\": {", + " \"End\": true,", + " \"Result\": \"World\",", + " \"Type\": \"Pass\"", + " }", + " }", + "}" + ] + ] + }, + "RoleArn": { + "Fn::GetAtt": [ + "MyStateMachineRole", + "Arn" + ] + }, + "Tags": [ + { + "Key": "stateMachine:createdBy", + "Value": "SAM" + } + ] + }, + "Type": "AWS::StepFunctions::StateMachine" + }, + "MyStateMachineGetApiRole": { + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "apigateway.amazonaws.com" + ] + } + } + ], + "Version": "2012-10-17" + }, + "Policies": [ + { + "PolicyDocument": { + "Statement": [ + { + "Action": "states:StartExecution", + "Effect": "Allow", + "Resource": { + "Ref": "MyStateMachine" + } + } + ] + }, + "PolicyName": "MyStateMachineGetApiRoleStartExecutionPolicy" + } + ] + }, + "Type": "AWS::IAM::Role" + }, + "MyStateMachinePostApiRole": { + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "apigateway.amazonaws.com" + ] + } + } + ], + "Version": "2012-10-17" + }, + "Policies": [ + { + "PolicyDocument": { + "Statement": [ + { + "Action": "states:StartExecution", + "Effect": "Allow", + "Resource": { + "Ref": "MyStateMachine" + } + } + ] + }, + "PolicyName": "MyStateMachinePostApiRoleStartExecutionPolicy" + } + ] + }, + "Type": "AWS::IAM::Role" + }, + "MyStateMachineRole": { + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "states.amazonaws.com" + ] + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [], + "Policies": [ + { + "PolicyDocument": { + "Statement": [ + { + "Action": "*", + "Effect": "Deny", + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "MyStateMachineRolePolicy0" + } + ], + "Tags": [ + { + "Key": "stateMachine:createdBy", + "Value": "SAM" + } + ] + }, + "Type": "AWS::IAM::Role" + }, + "ServerlessRestApi": { + "Properties": { + "Body": { + "info": { + "title": { + "Ref": "AWS::StackName" + }, + "version": "1.0" + }, + "paths": { + "/pathpost": { + "post": { + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Bad Request" + } + }, + "x-amazon-apigateway-integration": { + "credentials": { + "Fn::GetAtt": [ + "MyStateMachinePostApiRole", + "Arn" + ] + }, + "httpMethod": "POST", + "requestTemplates": { + "application/json": { + "Fn::Sub": "{\"input\": \"$util.escapeJavaScript($input.json('$'))\", \"stateMachineArn\": \"${MyStateMachine}\"}" + } + }, + "responses": { + "200": { + "statusCode": "200" + }, + "400": { + "statusCode": "400" + } + }, + "type": "aws", + "uri": { + "Fn::Sub": "arn:${AWS::Partition}:apigateway:${AWS::Region}:states:action/StartExecution" + } + } + } + } + }, + "swagger": "2.0" + } + }, + "Type": "AWS::ApiGateway::RestApi" + }, + "ServerlessRestApiDeployment5390046d30": { + "Properties": { + "Description": "RestApi deployment id: 5390046d30af30202ffeefe3944e76579b71af99", + "RestApiId": { + "Ref": "ServerlessRestApi" + }, + "StageName": "Stage" + }, + "Type": "AWS::ApiGateway::Deployment" + }, + "ServerlessRestApiProdStage": { + "Properties": { + "DeploymentId": { + "Ref": "ServerlessRestApiDeployment5390046d30" + }, + "RestApiId": { + "Ref": "ServerlessRestApi" + }, + "StageName": "Prod" + }, + "Type": "AWS::ApiGateway::Stage" + } + } +} diff --git a/tests/translator/output/state_machine_with_api_single.json b/tests/translator/output/state_machine_with_api_single.json new file mode 100644 index 000000000..aca9c79ba --- /dev/null +++ b/tests/translator/output/state_machine_with_api_single.json @@ -0,0 +1,251 @@ +{ + "Metadata": { + "SamTransformTest": true + }, + "Outputs": { + "ApiEndpoint": { + "Value": { + "Fn::Sub": "https://${MyApi}.execute-api.${AWS::Region}.${AWS::URLSuffix}/Prod/echo" + } + } + }, + "Resources": { + "HelloWorldFunction": { + "Properties": { + "Code": { + "ZipFile": "def handler(event, context):\n print(event)\n return \"do nothing\"\n" + }, + "Handler": "index.handler", + "Role": { + "Fn::GetAtt": [ + "HelloWorldFunctionRole", + "Arn" + ] + }, + "Runtime": "python3.8", + "Tags": [ + { + "Key": "lambda:createdBy", + "Value": "SAM" + } + ] + }, + "Type": "AWS::Lambda::Function" + }, + "HelloWorldFunctionRole": { + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "Tags": [ + { + "Key": "lambda:createdBy", + "Value": "SAM" + } + ] + }, + "Type": "AWS::IAM::Role" + }, + "MyApi": { + "Properties": { + "Body": { + "info": { + "title": { + "Ref": "AWS::StackName" + }, + "version": "1.0" + }, + "paths": { + "/echo": { + "post": { + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Bad Request" + } + }, + "x-amazon-apigateway-integration": { + "credentials": { + "Fn::GetAtt": [ + "PostPostEchoRole", + "Arn" + ] + }, + "httpMethod": "POST", + "requestTemplates": { + "application/json": { + "Fn::Sub": "{\"input\": \"$util.escapeJavaScript($input.json('$')).replaceAll(\"\\\\'\",\"'\")\", \"stateMachineArn\": \"${Post}\"}" + } + }, + "responses": { + "200": { + "statusCode": "200" + }, + "400": { + "statusCode": "400" + } + }, + "type": "aws", + "uri": { + "Fn::Sub": "arn:${AWS::Partition}:apigateway:${AWS::Region}:states:action/StartExecution" + } + } + } + } + }, + "swagger": "2.0" + } + }, + "Type": "AWS::ApiGateway::RestApi" + }, + "MyApiDeployment5866b9014d": { + "Properties": { + "Description": "RestApi deployment id: 5866b9014d5a1c815da161bacc3b15b4a19f95ef", + "RestApiId": { + "Ref": "MyApi" + }, + "StageName": "Stage" + }, + "Type": "AWS::ApiGateway::Deployment" + }, + "MyApiProdStage": { + "Properties": { + "DeploymentId": { + "Ref": "MyApiDeployment5866b9014d" + }, + "RestApiId": { + "Ref": "MyApi" + }, + "StageName": "Prod" + }, + "Type": "AWS::ApiGateway::Stage" + }, + "Post": { + "Properties": { + "DefinitionString": { + "Fn::Join": [ + "\n", + [ + "{", + " \"StartAt\": \"One\",", + " \"States\": {", + " \"One\": {", + " \"End\": true,", + " \"Resource\": \"${definition_substitution_1}\",", + " \"Type\": \"Task\"", + " }", + " }", + "}" + ] + ] + }, + "DefinitionSubstitutions": { + "definition_substitution_1": { + "Fn::GetAtt": [ + "HelloWorldFunction", + "Arn" + ] + } + }, + "RoleArn": { + "Fn::GetAtt": [ + "PostRole", + "Arn" + ] + }, + "Tags": [ + { + "Key": "stateMachine:createdBy", + "Value": "SAM" + } + ] + }, + "Type": "AWS::StepFunctions::StateMachine" + }, + "PostPostEchoRole": { + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "apigateway.amazonaws.com" + ] + } + } + ], + "Version": "2012-10-17" + }, + "Policies": [ + { + "PolicyDocument": { + "Statement": [ + { + "Action": "states:StartExecution", + "Effect": "Allow", + "Resource": { + "Ref": "Post" + } + } + ] + }, + "PolicyName": "PostPostEchoRoleStartExecutionPolicy" + } + ] + }, + "Type": "AWS::IAM::Role" + }, + "PostRole": { + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "states.amazonaws.com" + ] + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + "arn:aws:iam::aws:policy/AWSLambda_FullAccess" + ], + "Tags": [ + { + "Key": "stateMachine:createdBy", + "Value": "SAM" + } + ] + }, + "Type": "AWS::IAM::Role" + } + } +}