Open mingley opened 3 years ago
I tried the template above using a translator test and got the json below. It has no separate role definition.
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "sam template \n",
"Resources": {
"stateMachine": {
"Type": "AWS::Serverless::stateMachine",
"Properties": {
"DefinitionUri": "statemachine/state_machine_logic_here.asl.json",
"DefinitionSubstitutions": {
"firstFunctionArn": {
"Fn::GetAtt": [
"firstFunction",
"Arn"
]
},
"secondFunctionArn": {
"Fn::GetAtt": [
"secondFunction",
"Arn"
]
},
"thridFunctionArn": {
"Fn::GetAtt": [
"thirdFunction",
"Arn"
]
},
"fourthFunctionArn": {
"Fn::GetAtt": [
"fourthFunction",
"Arn"
]
}
},
"Events": {
"ApiEvent": {
"Type": "Api",
"Properties": {
"Method": "get",
"Path": "/activate_state_machine"
}
}
},
"Role": "arn:aws:iam::13333333333337:role/service-role/rolename"
}
},
"firstFunction": {
"Type": "AWS::Lambda::Function",
"Properties": {
"Code": {
"S3Bucket": "functions",
"S3Key": "first/"
},
"Handler": "app.lambda_handler",
"Role": "arn:aws:iam::13333333333337:role/rolename",
"Runtime": "python3.8",
"Tags": [
{
"Key": "lambda:createdBy",
"Value": "SAM"
}
]
}
},
"firstFunctionApiEventPermissionProd": {
"Type": "AWS::Lambda::Permission",
"Properties": {
"Action": "lambda:InvokeFunction",
"FunctionName": {
"Ref": "firstFunction"
},
"Principal": "apigateway.amazonaws.com",
"SourceArn": {
"Fn::Sub": [
"arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/first",
{
"__ApiId__": {
"Ref": "ServerlessRestApi"
},
"__Stage__": "*"
}
]
}
}
},
"secondFunction": {
"Type": "AWS::Lambda::Function",
"Properties": {
"Code": {
"S3Bucket": "functions",
"S3Key": "second/"
},
"Handler": "app.lambda_handler",
"Role": "arn:aws:iam::13333333333337:role/rolename",
"Runtime": "python3.8",
"Tags": [
{
"Key": "lambda:createdBy",
"Value": "SAM"
}
]
}
},
"secondFunctionApiEventPermissionProd": {
"Type": "AWS::Lambda::Permission",
"Properties": {
"Action": "lambda:InvokeFunction",
"FunctionName": {
"Ref": "secondFunction"
},
"Principal": "apigateway.amazonaws.com",
"SourceArn": {
"Fn::Sub": [
"arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/POST/second",
{
"__ApiId__": {
"Ref": "ServerlessRestApi"
},
"__Stage__": "*"
}
]
}
}
},
"thirdFunction": {
"Type": "AWS::Lambda::Function",
"Properties": {
"Code": {
"S3Bucket": "functions",
"S3Key": "third/"
},
"Handler": "app.lambda_handler",
"Role": "arn:aws:iam::13333333333337:role/rolename",
"Runtime": "python3.8",
"Tags": [
{
"Key": "lambda:createdBy",
"Value": "SAM"
}
]
}
},
"thirdFunctionApiEventPermissionProd": {
"Type": "AWS::Lambda::Permission",
"Properties": {
"Action": "lambda:InvokeFunction",
"FunctionName": {
"Ref": "thirdFunction"
},
"Principal": "apigateway.amazonaws.com",
"SourceArn": {
"Fn::Sub": [
"arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/POST/third",
{
"__ApiId__": {
"Ref": "ServerlessRestApi"
},
"__Stage__": "*"
}
]
}
}
},
"fourthFunction": {
"Type": "AWS::Lambda::Function",
"Properties": {
"Code": {
"S3Bucket": "functions",
"S3Key": "fourth/"
},
"Handler": "app.lambda_handler",
"Role": "arn:aws:iam::13333333333337:role/rolename",
"Runtime": "python3.8",
"Tags": [
{
"Key": "lambda:createdBy",
"Value": "SAM"
}
]
}
},
"fourthFunctionApiEventPermissionProd": {
"Type": "AWS::Lambda::Permission",
"Properties": {
"Action": "lambda:InvokeFunction",
"FunctionName": {
"Ref": "fourthFunction"
},
"Principal": "apigateway.amazonaws.com",
"SourceArn": {
"Fn::Sub": [
"arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/POST/fourth",
{
"__ApiId__": {
"Ref": "ServerlessRestApi"
},
"__Stage__": "*"
}
]
}
}
},
"ServerlessRestApi": {
"Type": "AWS::ApiGateway::RestApi",
"Properties": {
"Body": {
"swagger": "2.0",
"info": {
"version": "1.0",
"title": {
"Ref": "AWS::StackName"
}
},
"paths": {
"/first": {
"get": {
"x-amazon-apigateway-integration": {
"type": "aws_proxy",
"httpMethod": "POST",
"uri": {
"Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${firstFunction.Arn}/invocations"
}
},
"responses": {}
}
},
"/second": {
"post": {
"x-amazon-apigateway-integration": {
"type": "aws_proxy",
"httpMethod": "POST",
"uri": {
"Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${secondFunction.Arn}/invocations"
}
},
"responses": {}
}
},
"/third": {
"post": {
"x-amazon-apigateway-integration": {
"type": "aws_proxy",
"httpMethod": "POST",
"uri": {
"Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${thirdFunction.Arn}/invocations"
}
},
"responses": {}
}
},
"/fourth": {
"post": {
"x-amazon-apigateway-integration": {
"type": "aws_proxy",
"httpMethod": "POST",
"uri": {
"Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${fourthFunction.Arn}/invocations"
}
},
"responses": {}
}
}
}
}
}
},
"ServerlessRestApiDeployment507a4ca1c8": {
"Type": "AWS::ApiGateway::Deployment",
"Properties": {
"Description": "RestApi deployment id: 507a4ca1c886182e38decb467b549de7704fbd71",
"RestApiId": {
"Ref": "ServerlessRestApi"
},
"StageName": "Stage"
}
},
"ServerlessRestApiProdStage": {
"Type": "AWS::ApiGateway::Stage",
"Properties": {
"DeploymentId": {
"Ref": "ServerlessRestApiDeployment507a4ca1c8"
},
"RestApiId": {
"Ref": "ServerlessRestApi"
},
"StageName": "Prod"
}
}
},
"Outputs": {
"stateMachineArn": {
"Description": "state machine ARN",
"Value": {
"Ref": "stateMachine"
}
}
}
}
Hi @mikasd, I managed to get the same result as @Jacco did above, in which I could not find any AWS::IAM::Role
in the translated json template.
Can you share which SAM CLI version you are using? And can you also share what you saw when you ran sam build && sam deploy
?
Hi,
I am facing an issue related to SAM deployment with DeploymentPreference.
Description: I am trying to deploy a stack using SAM cli with DeploymentPreference
and the role for DeploymentPreference
is already mentioned in template but SAM is still trying to create a new role.
Below is the template:
AWSTemplateFormatVersion : '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: A SAM template to demostrate Prehook.
Resources:
genericRole:
Type: AWS::IAM::Role
Properties:
RoleName: a200338-dev-genericrole
PermissionsBoundary: !Sub arn:aws:iam::${AWS::AccountId}:policy/tr-permission-boundary
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
- kinesis.amazonaws.com
Action: 'sts:AssumeRole'
ManagedPolicyArns:
- 'arn:aws:iam::aws:policy/AWSLambdaFullAccess'
- 'arn:aws:iam::aws:policy/AmazonS3FullAccess'
- 'arn:aws:iam::aws:policy/AmazonKinesisFullAccess'
- 'arn:aws:iam::aws:policy/CloudWatchLogsFullAccess'
- 'arn:aws:iam::aws:policy/AWSCodeDeployFullAccess'
CodeDeployAssetOverrideRole:
Type: AWS::IAM::Role
Properties:
RoleName: a200338-codedeployRole
PermissionsBoundary: !Sub 'arn:aws:iam::${AWS::AccountId}:policy/tr-permission-boundary'
ManagedPolicyArns:
- "arn:aws:iam::aws:policy/service-role/AWSCodeDeployRoleForLambda"
Policies:
- PolicyName: a200338-CodeDeployTraffic-asset-override-policy
PolicyDocument:
Version: "2012-10-17"
Statement:
- Action:
- "lambda:InvokeFunction"
Resource: "*"
Effect: Allow
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Action:
- "sts:AssumeRole"
Effect: Allow
Principal:
Service:
- "codedeploy.amazonaws.com"
loaderLambda:
Type: AWS::Serverless::Function
Properties:
FunctionName: !Sub '${AWS::StackName}-loaderLambda'
Handler: lambda_function.lambda_handler
Runtime: python3.8
PackageType: Zip
CodeUri: ./poc_loader
AutoPublishAlias: live
Environment:
Variables:
target_bucket: a200338-preprodgcsbackupbucket
target_stream: a200338-preprodgcsKinesis
Role: !GetAtt genericRole.Arn
DeploymentPreference:
Type: AllAtOnce
Role: !GetAtt CodeDeployAssetOverrideRole.Arn
Hooks:
PreTraffic: !Ref loaderPreTrafficHookLambda
PostTraffic: !Ref loaderPostTrafficHookLambda
Events:
S3Event:
Type: S3
Properties:
Bucket: !Ref gcsLoadFilesBucket
Events: s3:ObjectCreated:Put
gcsLoadFilesBucket:
Type: AWS::S3::Bucket
Description: S3 bucket to store xml files
Properties:
BucketName: a200338-preprodgcsloadfilesbucket
gcsBackupBucket:
Type: AWS::S3::Bucket
Description: S3 bucket to store xml files
Properties:
BucketName: a200338-preprodgcsbackupbucket
gcsKinesis:
Type: 'AWS::Kinesis::Stream'
Properties:
Name: a200338-preprodgcsKinesis
RetentionPeriodHours: 24
ShardCount: 1
loaderPreTrafficHookLambda:
Type: AWS::Serverless::Function
Properties:
FunctionName: !Sub '${AWS::StackName}-loaderPreTrafficHookLambda'
Handler: prehook.lambda_handler
Runtime: python3.8
PackageType: Zip
CodeUri: ./traffic_hooks
Role: !GetAtt genericRole.Arn
DeploymentPreference:
Enabled: false
Timeout: 300
Environment:
Variables:
target_function: !Ref loaderLambda.Version
loaderPostTrafficHookLambda:
Type: AWS::Serverless::Function
Properties:
FunctionName: !Sub '${AWS::StackName}-loaderPostTrafficHookLambda'
Handler: posthook.lambda_handler
Runtime: python3.8
PackageType: Zip
CodeUri: ./traffic_hooks
Role: !GetAtt genericRole.Arn
DeploymentPreference:
Enabled: false
Timeout: 300
Environment:
Variables:
target_bucket: a200338-preprodgcsloadfilesbucket
Commands executed:
sam build
sam deploy --stack-name a200338-soumen-test --s3-bucket <passing an existing bucket name> --capabilities CAPABILITY_NAMED_IAM --profile <passing my saved aws profile name>
CLI output logs:
Deploying with following values
===============================
Stack name : a200338-soumen-test
Region : us-east-1
Confirm changeset : False
Deployment s3 bucket : a200338-tr-dev-poc-us-east-1-cfn
Capabilities : ["CAPABILITY_NAMED_IAM"]
Parameter overrides : {}
Signing Profiles : {}
Initiating deployment
=====================
Waiting for changeset to be created..
CloudFormation stack changeset
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Operation LogicalResourceId ResourceType Replacement
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ Add CodeDeployAssetOverrideRole AWS::IAM::Role N/A
+ Add CodeDeployServiceRole AWS::IAM::Role N/A
+ Add ServerlessDeploymentApplication AWS::CodeDeploy::Application N/A
+ Add gcsBackupBucket AWS::S3::Bucket N/A
+ Add gcsKinesis AWS::Kinesis::Stream N/A
+ Add gcsLoadFilesBucket AWS::S3::Bucket N/A
+ Add genericRole AWS::IAM::Role N/A
+ Add loaderLambdaAliaslive AWS::Lambda::Alias N/A
+ Add loaderLambdaDeploymentGroup AWS::CodeDeploy::DeploymentGroup N/A
+ Add loaderLambdaS3EventPermission AWS::Lambda::Permission N/A
+ Add loaderLambdaVersion5e53c5d302 AWS::Lambda::Version N/A
+ Add loaderLambda AWS::Lambda::Function N/A
+ Add loaderPostTrafficHookLambda AWS::Lambda::Function N/A
+ Add loaderPreTrafficHookLambda AWS::Lambda::Function N/A
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Changeset created successfully. arn:aws:cloudformation:us-east-1:xxxxxxxxxxxx:changeSet/samcli-deploy1614691356/d11e5f97-924c-411b-9db2-aedfb8952074
2021-03-02 18:52:45 - Waiting for stack create/update to complete
CloudFormation events from changeset
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
ResourceStatus ResourceType LogicalResourceId ResourceStatusReason
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
CREATE_IN_PROGRESS AWS::CodeDeploy::Application ServerlessDeploymentApplication -
CREATE_IN_PROGRESS AWS::Kinesis::Stream gcsKinesis -
CREATE_IN_PROGRESS AWS::S3::Bucket gcsBackupBucket -
CREATE_IN_PROGRESS AWS::IAM::Role CodeDeployServiceRole Did not have IAM permissions to process tags on
AWS::IAM::Role resource.
CREATE_IN_PROGRESS AWS::IAM::Role CodeDeployAssetOverrideRole Resource creation Initiated
CREATE_IN_PROGRESS AWS::IAM::Role genericRole Resource creation Initiated
CREATE_IN_PROGRESS AWS::IAM::Role CodeDeployServiceRole -
CREATE_COMPLETE AWS::CodeDeploy::Application ServerlessDeploymentApplication -
CREATE_IN_PROGRESS AWS::S3::Bucket gcsBackupBucket Resource creation Initiated
CREATE_IN_PROGRESS AWS::IAM::Role CodeDeployAssetOverrideRole -
CREATE_IN_PROGRESS AWS::CodeDeploy::Application ServerlessDeploymentApplication Resource creation Initiated
CREATE_IN_PROGRESS AWS::IAM::Role genericRole -
CREATE_FAILED AWS::Kinesis::Stream gcsKinesis Resource creation cancelled
CREATE_FAILED AWS::IAM::Role CodeDeployAssetOverrideRole Resource creation cancelled
CREATE_FAILED AWS::S3::Bucket gcsBackupBucket Resource creation cancelled
CREATE_FAILED AWS::IAM::Role genericRole Resource creation cancelled
CREATE_IN_PROGRESS AWS::Kinesis::Stream gcsKinesis Resource creation Initiated
CREATE_FAILED AWS::IAM::Role CodeDeployServiceRole API: iam:CreateRole User:
arn:aws:sts::xxxxxxxxxxxx:assumed-role/a200338-Po
werUser2/xxxxxxxx is not
authorized to perform: iam:CreateRole on
resource:
arn:aws:iam::xxxxxxxxxxxx:role/a200338-soumen-
test-CodeDeployServiceRole-1G9WIUIYG88B3
ROLLBACK_IN_PROGRESS AWS::CloudFormation::Stack a200338-soumen-test The following resource(s) failed to create:
[gcsKinesis, CodeDeployServiceRole,
CodeDeployAssetOverrideRole, genericRole,
gcsBackupBucket]. Rollback requested by user.
DELETE_IN_PROGRESS AWS::IAM::Role CodeDeployAssetOverrideRole -
DELETE_IN_PROGRESS AWS::IAM::Role genericRole -
DELETE_IN_PROGRESS AWS::S3::Bucket gcsBackupBucket -
DELETE_IN_PROGRESS AWS::CodeDeploy::Application ServerlessDeploymentApplication -
DELETE_COMPLETE AWS::S3::Bucket gcsBackupBucket -
DELETE_COMPLETE AWS::CodeDeploy::Application ServerlessDeploymentApplication -
DELETE_IN_PROGRESS AWS::Kinesis::Stream gcsKinesis -
DELETE_COMPLETE AWS::IAM::Role CodeDeployServiceRole -
DELETE_COMPLETE AWS::IAM::Role CodeDeployAssetOverrideRole -
DELETE_COMPLETE AWS::IAM::Role genericRole -
DELETE_COMPLETE AWS::Kinesis::Stream gcsKinesis -
ROLLBACK_COMPLETE AWS::CloudFormation::Stack a200338-soumen-test -
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Error: Failed to create/update the stack: a200338-soumen-test, Waiter StackCreateComplete failed: Waiter encountered a terminal failure state: For expression "Stacks[].StackStatus" we matched expected path: "ROLLBACK_COMPLETE" at least once
SAM CLI version : SAM CLI, version 1.18.2
Python version: Python 3.8.7
AWS CLI version: aws-cli/2.1.26 Python/3.7.9 Windows/10 exe/AMD64 prompt/off
Note: Aws account id and user id is intentionally modified before posting to xxxxxx...
@soumenrock You are trying to create IAM::Roles in your template (genericRole, CodeDeployAssetOverrideRole) while you don't have the iam:CreateRole
permission. That is why the deployment is failing.
@mikasd I tried your template and you are right; SAM always creates an IAM Role for the API that triggers that state-machine (StateMachineApiEventRole)
I think a new attribute "Role" is required for the API event source
I have the same issue as @soumenrock which is not surprising as I believe we are in the same organization. The issue is you can create IAM Roles, but the PermissionsBoundary is required to do so by policy. The implicit role created by the Api Event does not include that PermissionsBoundary, thus failing. I would agree that adding an attribute to specify the Role for API event source would resolve the issue.
Any new on this isse? I am unable to deploy due to missing PermissionsBoundary
in the implicit role.
Description: The app structure is an API with 5 routes, 4 of the endpoints hit individual lambdas and the fifth initiates a step function state machine process. All of this is built out with the SAM CLI tooling.
In my organization there is a strict IAM policy. I have managed to procure all of the Policies needed for the permissions associated with deploying a SAM CLI application under a role they gave me. From what I understand, the logic behind the IAM role creation permissions and the sam deploy function is essentially screening the application template for any roles needed, if roles are specified, it uses those roles, otherwise it auto generates ones specific to the needs of the application being deployed.
We are not allowed to have iam:createRole permissions.
I have tried to circumvent this by getting the roles with all of the theoretical permissions needed and then specifying those roles into the formation template.
In the template, all of the lambdas have roles specified and during deployment the build tasks of creating roles for each lambda were removed as a result. This is expected functionality.
I have specified a role for the state machine in the template as well, the role has the full access policy for step functions along with all other needed permissions.
The event type to activate the state machine is an api event. During deployment, there is still a trigger to create a new iam role related to the state machines specific api event. Providing the predefined role to every other resource seemed to do the trick. Why does it keep doing this only for the state machines api event?
Just to emphasize, I fixed this issue for the lambdas and the autogenerated api by specifying roles for each resource, but for some reason it did not work with the state machine's api event.
I have tried this with capabilities defined as both CAPABILITY_IAM and CAPABILITY_NAMED_IAM in the deploy command.
I used issue #1009 to fix the role issues with the Lambdas but the same logic did not work for the state machine resource.
here is the template yaml for reference, the naming or references might be weird on here because I tried to scrub it for anything related to the actual project and make it general.
I am new so hopefully this is just a template syntax issue on my end.
Thank you in advance
Similar issue also posted but unasnwered on StackOverflow
Observed result:
CloudFormation attempts to create a state machine api event role, and fails because current aws role hasn't been granted permissions to create IAM Roles.
Expected result:
The deployment should succeed because CloudFormation should NOT create a new role, as a Role has already been provided in the SAM template.