Cloudformation condition on parameter in Role policy - amazon-web-services

I am creating iam role and its managed policy. In managed policy I want to give allow access to invoke API(Gateway). This template is going to execute on at least 6 environments I want to use condition based approach to assign API gateway url in resource so that template will be easy to maintain and execute.
Based on type of environment API url is going to change.
AWSTemplateFormatVersion: 2010-09-09
Description: >-
This template creates Role and policy
Parameters:
envname:
Type: String
Description: Enter envname
AllowedValues:
- dev
- dev2
- sit
- uat
- prf
- prod
prodaccountid:
Type: String
Description: Enter Prod AccountID
Resources:
DeviceRole:
Type: 'AWS::IAM::Role'
Properties:
RoleName: 'DeviceRole'
MaxSessionDuration : 43200
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
AWS: !Join ["",[!Sub 'arn:aws:iam::${AWS::AccountId}:role/',!Ref envname,'_Role']]
Service: lambda.amazonaws.com
Action:
- 'sts:AssumeRole'
- Effect: Allow
Principal:
AWS: !Sub 'arn:aws:iam::${AWS::AccountId}:user/test-user'
Service: lambda.amazonaws.com
Action:
- 'sts:AssumeRole'
DevicePolicy:
Type: 'AWS::IAM::ManagedPolicy'
Properties:
Description: >-
This Policy will be attached to the device role
ManagedPolicyName: !Join
- ''
- - 'DeviceConnectPolicy'
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action: 'execute-api:Invoke'
**Resource:
- !Join ["", [!Sub 'arn:aws:execute-api:${AWS::Region}:',!Ref prodaccountid,':aaaaaaaaaa/Test/PUT']]
- !Join ["", [!Sub 'arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:bbbbbbbbbb/*/PUT/*/*/*/v2']]
- !Join ["", [!Sub 'arn:aws:execute-api:${AWS::Region}:',!Ref prodaccountid,':cccccccccc/*/PUT/v2/s']]
- !Join ["", [!Sub 'arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:dddddddddd/*/PUT/*/*/*/v2']]**
Roles:
- Ref: DeviceRole
I want to use conditions in Resource.
Thanks in advance

Related

Can't create a AWS Batch JobDefinition JobRoleArn in Cloudformation using a !Ref

I'm trying to create a Batch setup in Cloudformation. I have in Resources an IAM Role:
SecretsAndS3AccessRole:
Type: 'AWS::IAM::Role'
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service: batch.amazonaws.com
Action: 'sts:AssumeRole'
- Effect: Allow
Principal:
Service: ec2.amazonaws.com
Action: 'sts:AssumeRole'
- Effect: Allow
Principal:
Service: ecs-tasks.amazonaws.com
Action: 'sts:AssumeRole'
ManagedPolicyArns:
- 'arn:aws:iam::aws:policy/SecretsManagerReadWrite'
- 'arn:aws:iam::aws:policy/AmazonS3FullAccess'
- 'arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy'
Then in my JobDefinition I have:
JobDefinition:
Type: 'AWS::Batch::JobDefinition'
Properties:
Type: container
ContainerProperties:
Image: public.ecr.aws/l0v4l2q2/rapidtide-cloud
Vcpus: 2
Memory: 2000
Command:
- /simple-test
Privileged: true
JobRoleArn: !Ref SecretsAndS3AccessRole
ExecutionRoleArn: !Ref SecretsAndS3AccessRole
Secrets:
- Name: MY_SECRET
ValueFrom: arn:aws:secretsmanager:us-east-1:123456789:secret:MYSECRET-zSQVSQ
RetryStrategy:
Attempts: 1
When I try to build the stack, I get:
An error occurred (ClientException) when calling the RegisterJobDefinition operation: Error executing request, Exception : executionRoleArn bothrefs-SecretsAndS3AccessRole-1INAOWFBH2SK2 is not an iam role arn
If I remove the ExecutionRoleArn line and the Secrets, the stack builds fine, which is to say that JobRoleArn is happy with a value of !Ref SecretsAndS3AccessRole. (But I need the secrets, and to use secrets you need an execution role.) And if I hardcode the ARN there, it works fine.
What is different about ExecutionRoleArn that it doesn't allow a !Ref? According to the documentation for JobDefinition/ContainerProperties, JobRoleArn and ExecutionRoleArn seem the same sort of object.
!Ref returns the logical ID of the resource, not the ARN.
You need to use !GetAtt.
This should work:
ExecutionRoleArn: !GetAtt SecretsAndS3AccessRole.Arn

CloudFormation CodePipeline template is not authorized to preform AssumeRole, why?

for days I have not been able to figure out why one AWS role is not authorized to perform AssumeRole on another. In this case I have a dev-account with AWS CodeCommit on it, and a tools account with CodePipeline. I am trying to allow CodePipeline (in tools) to access CodeCommit (in dev), but am always told that the role in tools is not authorized to do so.
Here is my CloudFormation template to create a role in dev:
AWSTemplateFormatVersion: "2010-09-09"
Description: Cross Account Role to Allow Access to CodePipeline in Tools Account
Parameters:
ToolsAccount:
Description: AWS AccountNumber for tools account
Type: Number
Resources:
Role:
Type: AWS::IAM::Role
Properties:
RoleName: access-codecommit-in-dev
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
AWS:
- !Ref ToolsAccount
Action:
- sts:AssumeRole
Path: /
Policy:
Type: AWS::IAM::Policy
Properties:
PolicyName: !Sub ToolsAcctCodePipelineCodeCommitPolicy
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- codecommit:BatchGetRepositories
- codecommit:Get*
- codecommit:GitPull
- codecommit:List*
- codecommit:CancelUploadArchive
- codecommit:UploadArchive
- s3:*
Resource: "*"
Roles:
- !Ref Role
Here is the CloudFormation template that creates CodePipeline:
Description: "Code pipeline to deploy frontend"
Parameters:
DevAccount:
Description: AWS AccountNumber for dev
Type: Number
TestAccount:
Description: AWS AccountNumber for test
Type: Number
Resources:
BuildProjectRole:
Type: AWS::IAM::Role
Properties:
RoleName: codebuild-role
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service:
- codebuild.amazonaws.com
Action:
- sts:AssumeRole
BuildProjectPolicy:
Type: AWS::IAM::Policy
Properties:
PolicyName: codebuild-policy
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- s3:PutObject
- s3:GetBucketPolicy
- s3:GetObject
- s3:ListBucket
Resource:
- "bucketNameHere"
- Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Resource: arn:aws:logs:*:*:*
Roles:
- !Ref BuildProjectRole
PipeLineRole:
Type: AWS::IAM::Role
Properties:
RoleName: codepipeline-role
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service:
- codepipeline.amazonaws.com
Action:
- sts:AssumeRole
PipelinePolicy:
Type: AWS::IAM::Policy
Properties:
PolicyName: codepipeline-policy
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- codepipeline:*
- iam:ListRoles
- cloudformation:Describe*
- cloudFormation:List*
- codecommit:List*
- codecommit:Get*
- codecommit:GitPull
- codecommit:UploadArchive
- codecommit:CancelUploadArchive
- codebuild:BatchGetBuilds
- codebuild:StartBuild
- cloudformation:CreateStack
- cloudformation:DeleteStack
- cloudformation:DescribeStacks
- cloudformation:UpdateStack
- cloudformation:CreateChangeSet
- cloudformation:DeleteChangeSet
- cloudformation:DescribeChangeSet
- cloudformation:ExecuteChangeSet
- cloudformation:SetStackPolicy
- cloudformation:ValidateTemplate
- iam:PassRole
- s3:ListAllMyBuckets
- s3:GetBucketLocation
Resource:
- "*"
- Effect: Allow
Action:
- s3:PutObject
- s3:GetBucketPolicy
- s3:GetObject
- s3:ListBucket
Resource:
- "bucketName"
- Effect: Allow
Action:
- sts:AssumeRole
Resource:
- !Sub arn:aws:iam::${DevAccount}:role/crossaccount-codecommit-access
Roles:
- !Ref PipeLineRole
FrontEndPipeline:
Type: "AWS::CodePipeline::Pipeline"
Properties:
ArtifactStore:
Type: "S3"
Location: "bucketName"
Name: "frontend-deploy"
RoleArn: !GetAtt PipeLineRole.Arn
Stages:
- Name: "Code-Fetch"
Actions:
- Name: "stage-source"
ActionTypeId:
Category: Source
Owner: AWS
Provider: CodeCommit
Version: 1
OutputArtifacts:
- Name: SourceCode
Configuration:
PollForSourceChanges: true
BranchName: develop
RepositoryName: "nameHere"
RunOrder: 1
RoleArn: !Sub arn:aws:iam::${DevAccount}:role/crossaccount-codecommit-access
- Name: Build
Actions:
- Name: "Build-Source"
ActionTypeId:
Category: Build
Owner: AWS
Version: "1"
Provider: CodeBuild
InputArtifacts:
- Name: SourceCode
OutputArtifacts:
- Name: DeployOutput
Configuration:
ProjectName: "CodeBuild"
RunOrder: 1
- Name: Deploy
Actions:
- Name: deploy
ActionTypeId:
Category: Deploy
Owner: AWS
Version: "1"
Provider: S3
InputArtifacts:
- Name: DeployOutput
Configuration:
BucketName: "bucketNameHere"
Extract: true
#RoleArn: !Sub arn:aws:iam::${TestAccount}:role/cloudformationdeployer-role
CodeBuildProject:
Type: AWS::CodeBuild::Project
Properties:
Name: "CodeBuild"
ServiceRole: !GetAtt BuildProjectRole.Arn
Artifacts:
Type: CODEPIPELINE
Environment:
ComputeType: BUILD_GENERAL1_SMALL
Type: LINUX_CONTAINER
Image: node:13
Source:
Type: CODEPIPELINE
What could possibly be generating this error:
arn:aws:iam::{ToolsAccount}:role/projectName-codepipeline-role is not authorized to perform AssumeRole on role arn:aws:iam::{DevAcciybt}:role/access-codecommit-in-dev (Service: AWSCodePipeline; Status Code: 400; Error Code: InvalidStructureException; Request ID: (ID here))
Does the role
arn:aws:iam::{ToolsAccount}:role/projectName-codepipeline-role have permission to assume the role in dev account something like below:
{
"Sid": "AssumeCrossAccountRole"
"Effect": "Allow",
"Actions": "sts:AssumeRole",
"Resource": "ARN of dev account role"
}
else
Try out with passing ARN arn:aws:iam::{ToolsAccount}:role/projectName-codepipeline-role in the AWS principal instead of account number for the role which you are creating in dev account

How could I output IAM role and use that in another stack?

I've two stacks called "createIAMRole", "createElasticSearch" and "createdLambda". What I want is I want to use IAM Role ARN from first stack called "createIAMRole" in both "createElasticSearch" and "createdLambda".
createIAMRole
AWSTemplateFormatVersion: '2010-09-09'
Description: >
blah.
Resources:
myIAMRole:
Type: AWS::IAM::Role
Properties:
..
..
Policies:
- PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action:
- dynamodb:*
Resource: "*"
PolicyName: "myIAMRolePolicy"
Outputs:
myIAMRole:
Description: myIAMRole to use Stacks
Value: !Ref myIAMRole
"createElasticSearch"
Resources:
ElasticsearchDomain:
Type: AWS::Elasticsearch::Domain
Properties:
..
..
AccessPolicies:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Principal:
AWS:
- >>> THERE IS I WANT TO ADD <<<
Action: "es:*"
Resource: "*"
AdvancedOptions:
rest.action.multi.allow_explicit_index: "true"
Please let me know how to do it, thanks.
For the createIAMRole you need to export the output:
Outputs: myIAMRole:
Description: myIAMRole to use Stacks
Value: !Ref myIAMRole
Export:
Name: myIAMRole
And for the createElasticSearch you need to "ImportValue":
Fn::ImportValue:
!Sub "${myIAMStackName}-myIAMRole"
More Information: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-importvalue.html
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/outputs-section-structure.html

Add retention policy to API Gateway logs published to CloudWatch

I have to add retention policy to API Gateway Cloudwatch logs, hence I cannot use the aws provided policy to do so i.e. arn:aws:iam::aws:policy/service-role/AmazonAPIGatewayPushToCloudWatchLogs
So instead I created my own role with custom policy :
ApiGatewayCloudWatchLogsRole:
Type: 'AWS::IAM::Role'
DependsOn: APIGFunctionLogGroup
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service:
- apigateway.amazonaws.com
Action: 'sts:AssumeRole'
Path: /
Policies:
- PolicyName: APIGatewayPushLogsPolicy
PolicyDocument:
Version: 2012-10-17
Statement:
Effect: Allow
Action:
- 'logs:CreateLogStream'
- 'logs:PutLogEvents'
- 'logs:DescribeLogGroups'
- 'logs:DescribeLogStreams'
- 'logs:GetLogEvents'
- 'logs:FilterLogEvents'
Resource: '*'
And then created LogGroup with retention as :
APIGFunctionLogGroup:
Type: 'AWS::Logs::LogGroup'
Properties:
RetentionInDays: 30
LogGroupName: !Join
- ''
- - API-Gateway-Execution-Logs_
- !Ref MyRestApi
And passed the above created role to AWS::ApiGateway::Account
ApiGatewayAccount:
Type: 'AWS::ApiGateway::Account'
DependsOn: APIGFunctionLogGroup
Properties:
CloudWatchRoleArn: !GetAtt
- ApiGatewayCloudWatchLogsRole
- Arn
But while deploying my API Gateway I am getting error as :
I have the trust policy as well but API Gateway Account is not getting created.
If you create the log group yourself, before APIgateway does you should be able to use the existing policy/service role.

The Service-Linked Role for this Auto Scaling group is not yet ready for use

I'm creating AWS CloudFormation template to add a lambda function as a life cycle hook. But the CloudFormation template deployment failed with below message:
The Service-Linked Role for this Auto Scaling group is not yet ready for use.
The CF template is written in YAML and the auto scaling group's part is as follows:
ServerGroup:
Type: 'AWS::AutoScaling::AutoScalingGroup'
DependsOn:
- VpcStack
- NodeManagerExecRole
- NodeManagerSnsTopic
Properties:
VPCZoneIdentifier:
- !GetAtt [VpcStack, Outputs.Subnet2Id]
LaunchConfigurationName: !Ref LaunchConfig2
MinSize: '0'
MaxSize: !Ref NodesPerZone
DesiredCapacity: !Ref NodesPerZone
Cooldown: '300'
HealthCheckType: EC2
HealthCheckGracePeriod: '300'
LoadBalancerNames:
- !Ref ElasticLoadBalancer
LifecycleHookSpecificationList:
- LifecycleTransition: 'autoscaling:EC2_INSTANCE_LAUNCHING'
LifecycleHookName: NodeManager
HeartbeatTimeout: 4800
NotificationTargetARN: !Ref NodeManagerSnsTopic
RoleARN: !GetAtt [NodeManagerExecRole, Arn]
The code snippet of NodeManagerExecRole is like this:
NodeManagerExecRole:
Type: 'AWS::IAM::Role'
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- 'sts:AssumeRole'
Policies:
- PolicyName: NodeManager
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- "sns:Publish"
Resource: "arn:aws:sns:*:*:*"
- Effect: Allow
Action:
- 'logs:CreateLogGroup'
- 'logs:CreateLogStream'
- 'logs:PutLogEvents'
Resource: 'arn:aws:logs:*:*:*'
I searched in AWS documentation as well as stackoverfolow and didn't find useful information about this error. It's only mentioned here with on detail informaton.
Is there something I'm missing in the template?
You would need to add a trust policy for autoscaling group to post to SNS.
"Principal": {
"Service": "autoscaling.amazonaws.com"
},