An error occurred (AccessDenied) when calling the CreateStack operation: - node.js

An error occurred (AccessDenied) when calling the CreateStack operation: User: arn:aws:iam::812520856627:user/dimitris is not authorized to perform: cloudformation:CreateStack on resource: arn:aws:cloudformation:us-west-2:812520856627:stack/blog-stage/*
I tried to run this on command :
aws cloudformation create-stack --stack-name blog-stage --template-body file://$PWD/stack.yml --profile demo --region us-west-2
Resources:
AppNode:
Type: AWS::EC2::Instance
Properties:
InstanceType: t2.micro
ImageId: ami-0c579621aaac8bade
KeyName: jimapos
SecurityGroups:
- !Ref AppNodeSG
AppNodeSG:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: for the app nodes that allow ssh, http and docker ports
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: '80'
ToPort: '80'
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: '22'
ToPort: '22'
CidrIp: 0.0.0.0/0

You are trying to create stack against User dimitris which is not authorized to perform cloudformation:CreateStack
To assign permission to the user goto https://console.aws.amazon.com/iam/home#/home -> users -> select user -> add permission
Try to add this policy with user dimitries.
Example A sample policy that grants create and view stack actions
{
"Version":"2012-10-17",
"Statement":[{
"Effect":"Allow",
"Action":[
"cloudformation:CreateStack",
"cloudformation:DescribeStacks",
"cloudformation:DescribeStackEvents",
"cloudformation:DescribeStackResources",
"cloudformation:GetTemplate",
"cloudformation:ValidateTemplate"
],
"Resource":"*"
}]
}
You can check this link to customize or restick policy to specific resources.
Either you can create custom policy or you can attach the below-existing one.

Related

AWS XRAY on Fargate service

I want to add xray to my Fargate service. Everything works (synth/deploy) but in the logs I'am seeing the following error:
2022-02-07T13:38:22Z [Error] Sending segment batch failed with:
AccessDeniedException: 2022-02-07 14:38:22status code: 403, request
id: cdc23f61-5c2e-4ede-8bda-5328e0c8ac8f
The user I'am using to deploy the application has the AWSXrayFullAccess permission.
Do I have to grant the task the permission manually? If so how?
Here is a snippet of the application:
const cdk = require('#aws-cdk/core');
const ecs = require('#aws-cdk/aws-ecs');
const ecsPatterns = require('#aws-cdk/aws-ecs-patterns');
class API extends cdk.Stack {
constructor(parent, id, props) {
super(parent, id, props);
this.apiXRayTaskDefinition = new ecs.FargateTaskDefinition(this, 'apixRay-definition', {
cpu: 256,
memoryLimitMiB: 512,
});
this.apiXRayTaskDefinition.addContainer('api', {
image: ecs.ContainerImage.fromAsset('./api'),
environment: {
"QUEUE_URL": props.queue.queueUrl,
"TABLE": props.table.tableName,
"AWS_XRAY_DAEMON_ADDRESS": "0.0.0.0:2000"
},
logging: ecs.LogDriver.awsLogs({ streamPrefix: 'api' }),
}).addPortMappings({
containerPort: 80
})
this.apiXRayTaskDefinition.addContainer('xray', {
image: ecs.ContainerImage.fromRegistry('public.ecr.aws/xray/aws-xray-daemon:latest'),
logging: ecs.LogDriver.awsLogs({ streamPrefix: 'xray' }),
}).addPortMappings({
containerPort: 2000,
protocol: ecs.Protocol.UDP,
});
// API
this.api = new ecsPatterns.ApplicationLoadBalancedFargateService(this, 'api', {
cluster: props.cluster,
taskDefinition: this.apiXRayTaskDefinition,
desiredCount: 2,
cpu: 256,
memory: 512,
createLogs: true
})
props.queue.grantSendMessages(this.api.service.taskDefinition.taskRole);
props.table.grantReadWriteData(this.api.service.taskDefinition.taskRole);
}
}
The user I'am using to deploy the application has the AWSXrayFullAccess permission.
This is irrelevant, the task will not get all the rights of the user that deploys the stack.
Yes, you need to add the required permissions to the task with
this.apiXRayTaskDefinition.taskRole.addManagedPolicy(
iam.ManagedPolicy.fromAwsManagedPolicyName('AWSXRayDaemonWriteAccess')
);
References:
AWS managed policy with required access for the X-Ray daemon: https://docs.aws.amazon.com/xray/latest/devguide/security_iam_id-based-policy-examples.html#xray-permissions-managedpolicies
Import an AWS-managed policy: https://docs.aws.amazon.com/cdk/api/v1/docs/#aws-cdk_aws-iam.ManagedPolicy.html#static-fromwbrawswbrmanagedwbrpolicywbrnamemanagedpolicyname
Access the task role: https://docs.aws.amazon.com/cdk/api/v1/docs/#aws-cdk_aws-ecs.FargateTaskDefinition.html#taskrole-1
Add a policy: https://docs.aws.amazon.com/cdk/api/v1/docs/#aws-cdk_aws-iam.IRole.html#addwbrmanagedwbrpolicypolicy

create log group and log stream using serverless framework

I have the following Terraform code. How can I implement the same in Serverless framework?
resource "aws_cloudwatch_log_group" "abc" {
name = logGroupName
tags = tags
}
resource "aws_cloudwatch_log_stream" "abc" {
depends_on = ["aws_cloudwatch_log_group.abc"]
name = logStreamName
log_group_name = logGroupName
}
My Serverless.yml file looks more like this. Basically I need to create a Log Group and Log Stream with names.
provider:
name: aws
runtime: python3.7
cfnRole: arn:cfnRole
iamRoleStatements:
- Effect: 'Allow'
Action:
- lambda:InvokeFunction
Resource: 'arn....'
functions:
handle:
handler: handler.handle
events:
- schedule:
rate: rate (2 hours)
resources:
Resources:
IamRoleLambdaExecution:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action: sts:AssumeRole
In your Resources you have to add AWS::Logs::LogGroup and AWS::Logs::LogStream.
But tags on AWS::Logs::LogGroup are not supported.

API gateway returns 401 and doesn't invoke custom authorizer

I've implemented a custom 'REQUEST' type authorizer for an API gateway which validates a JWT token passed in the 'Authorization' header. I've tested the lambda independently and it works as expected. I've also attached the authorizer to my routes and I can test it in the AWS console - again, everything seems to work (see image):
successful invoke via console
However, when I try to invoke my endpoints with the token in the Authorization header, I always receive an UNAUTHORIZED response:
{
"errors": [
{
"category": "ClientError",
"code": "UNAUTHORIZED",
"detail": "Unauthorized",
"method": "GET",
"path": "/cases",
"requestId": "004eb254-a926-45ad-96a5-ce3527621c81",
"retryable": false
}
]
}
From what I have gathered, API gateway never invokes my Authorizer as i don't see any log events in its cloudwatch. I was able to enable cloudwatch logging of my API gateway, and the only log information I see is as follows:
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| timestamp | message |
|---------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1578275720543 | (dac0d4f6-1380-4049-bcee-bf776ca78e5c) Extended Request Id: F2v9WFfiIAMF-9w= |
| 1578275720543 | (dac0d4f6-1380-4049-bcee-bf776ca78e5c) Unauthorized request: dac0d4f6-1380-4049-bcee-bf776ca78e5c |
| 1578275720543 | (dac0d4f6-1380-4049-bcee-bf776ca78e5c) Extended Request Id: F2v9WFfiIAMF-9w= |
| 1578275720544 | (dac0d4f6-1380-4049-bcee-bf776ca78e5c) Gateway response type: UNAUTHORIZED with status code: 401 |
| 1578275720544 | (dac0d4f6-1380-4049-bcee-bf776ca78e5c) Gateway response body: {"errors": [{"category": "ClientError","code": "UNAUTHORIZED","detail": "Unauthorized","method": "GET","path": "/cases","requestId": "dac0d4f6-1380-4049-bcee-bf776ca78e5c","retryable": false }]} |
| 1578275720544 | (dac0d4f6-1380-4049-bcee-bf776ca78e5c) Gateway response headers: {} |
| 1578275720544 | (dac0d4f6-1380-4049-bcee-bf776ca78e5c) Gateway response type: UNAUTHORIZED with status code: 401 |
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
At this point I am completely stuck and not sure how to debug this further. I'm assuming something must be configured wrong but the log information I can find doesn't given any indication of what the problem is. I've also pasted a copy of my authorizers configuration in the image below:
Authorizer Configuration
Screenshot of one endpoint configured to use the authorizer
I figured out the problem I was having:
I needed to set identitySource: method.request.header.Authorization in the authorizer field of the endpoint as well as in the CF stack.
Custom Authorizer definition in raw cloudformation:
service:
name: api-base
frameworkVersion: ">=1.2.0 <2.0.0"
plugins:
- serverless-plugin-optimize
- serverless-offline
- serverless-pseudo-parameters
- serverless-domain-manager
custom:
stage: ${self:provider.stage, 'dev'}
serverless-offline:
port: ${env:OFFLINE_PORT, '4000'}
false: false
cognitoStack: marley-auth
customDomain:
domainName: ${env:BE_HOST, ''}
enabled: ${env:EN_CUSTOM_DOMAIN, self:custom.false}
stage: ${self:provider.stage, 'dev'}
createRoute53Record: true
provider:
name: aws
runtime: nodejs10.x
versionFunctions: true
apiName: public
logs:
restApi: true
stackTags:
COMMIT_SHA: ${env:COMMIT_SHA, 'NO-SHA'}
environment:
USER_POOL_ID: ${cf:${self:custom.cognitoStack}-${self:custom.stage}.UserPoolId}
CLIENT_ID: ${cf:${self:custom.cognitoStack}-${self:custom.stage}.UserPoolClientId}
timeout: 30
iamRoleStatements:
- Effect: "Allow"
Action:
- "lambda:InvokeFunction"
Resource: "*"
functions:
authorizer:
handler: handler/authorize.handler
resources:
- Outputs:
ApiGatewayRestApiId:
Value:
Ref: ApiGatewayRestApi
Export:
Name: ${self:custom.stage}-${self:provider.apiName}-ApiGatewayRestApiId
ApiGatewayRestApiRootResourceId:
Value:
Fn::GetAtt:
- ApiGatewayRestApi
- RootResourceId
Export:
Name: ${self:custom.stage}-${self:provider.apiName}-ApiGatewayRestApiRootResourceId
SharedAuthorizerId:
Value:
Ref: SharedAuthorizer
Export:
Name: ${self:custom.stage}-${self:provider.apiName}-ApiGatewaySharedAuthorizerId
- Resources:
SharedAuthorizer:
Type: AWS::ApiGateway::Authorizer
Properties:
Name: public
AuthorizerUri: !Join
- ''
- - 'arn:aws:apigateway:'
- !Ref 'AWS::Region'
- ':lambda:path/2015-03-31/functions/'
- !GetAtt
- AuthorizerLambdaFunction
- Arn
- /invocations
RestApiId: !Ref 'ApiGatewayRestApi'
Type: REQUEST
IdentitySource: method.request.header.Authorization
AuthorizerResultTtlInSeconds: '300'
DependsOn: AuthorizerLambdaFunction
ApiAuthLambdaPermission:
Type: AWS::Lambda::Permission
Properties:
Action: lambda:InvokeFunction
FunctionName: !Ref AuthorizerLambdaFunction
Principal: apigateway.amazonaws.com
SourceArn: !Sub "arn:aws:execute-api:#{AWS::Region}:#{AWS::AccountId}:#{ApiGatewayRestApi}/authorizers/*"
DependsOn: ApiGatewayRestApi
Using the authorizer in another stack - note that I have specified IdentitySource here as well as in the definition of the authorizer - for some reason I had to do it in both places.
authorizer:
type: CUSTOM
authorizerId: ${cf:api-base-${self:custom.stage}.SharedAuthorizerId}
identitySource: method.request.header.Authorization

Invalid HTTP endpoint specified for URI in Amazon ApiGateway

I am trying to create a resource /user/devices with GET method for API Gateway using cloudformation template but it is giving me a below error
An error occurred: ApiGatewayRootMethod - Invalid HTTP endpoint specified for URI (Service: AmazonApiGateway; Status Code: 400; Error Code: BadRequestException; Request ID:xxxxxxxxxx)
Below is my cloudformation template,
AWSTemplateFormatVersion: 2018-11-13
Description: test user
resources:
Resources:
UserDeviceApiGateway:
Type: "AWS::ApiGateway::RestApi"
Properties:
Name: "test-user-info"
Description: "Fetch the user"
UserResource:
Type: 'AWS::ApiGateway::Resource'
Properties:
ParentId:
Fn::GetAtt: ["UserDeviceApiGateway","RootResourceId"]
RestApiId:
Ref: "UserDeviceApiGateway"
PathPart: 'user'
Resource:
Type: 'AWS::ApiGateway::Resource'
Properties:
ParentId:
Ref: "UserResource"
RestApiId:
Ref: "UserDeviceApiGateway"
PathPart: 'devices'
ApiGatewayRootMethod:
Type: "AWS::ApiGateway::Method"
Properties:
AuthorizationType: "NONE"
HttpMethod: "GET"
Integration:
IntegrationHttpMethod: "GET"
Type: "HTTP"
Uri: Sub
- "arn:aws:apigateway:arn:aws:lambda:eu-west-1:lambda:path/2015-03-31/functions/arn:aws:lambda:eu-west-1:xxxxxxxx:function:user-device-lambda/invocations"
ResourceId:
Fn::GetAtt: ["UserDeviceApiGateway","RootResourceId"]
RestApiId:
Ref: "UserDeviceApiGateway"
Deployment:
DependsOn:
- ApiGatewayRootMethod
Type: 'AWS::ApiGateway::Deployment'
Properties:
RestApiId:
Ref: "UserDeviceApiGateway"
StageName: dev
A little late to the party but...
You specify Type: "HTTP" for ApiGatewayRootMethod but HTTP takes the API endpoint URL. The URI formation that you specify is taken by Type: "AWS".
From AWS docs:
The Uniform Resource Identifier (URI) for the integration.
If you specify HTTP for the Type property, specify the API endpoint URL.
If you specify MOCK for the Type property, don't specify this property.
If you specify AWS for the Type property, specify an AWS service that follows this form: arn:aws:apigateway:region:subdomain.service|service:path|action/service_api. For example, a Lambda function URI follows this form: arn:aws:apigateway:region:lambda:path/path. The path is usually in the form /2015-03-31/functions/LambdaFunctionARN/invocations. For more information, see the uri property of the Integration resource in the Amazon API Gateway REST API Reference.
If you specified HTTP or AWS for the Type property, you must specify this property.
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-apitgateway-method-integration.html

Not getting any external outbound traffic from nodes in a Azure VM Scale Set behind a loadbalancer

I'm experiencing difficulties regarding accessing external resources from nodes (RHEL) configured in a VM Scale Set.
To sketch the environment I'm trying to describe using Azure Resource Manager Templates, I'm looking to create:
1 common virtualNetwork
1 Frontend VM (running RHEL, and is working as intended)
1 Cluster (vmss) running 2 nodes (RHEL)
Nodes are spawned in the same private subnet as the frontend VM
1 loadbalancer should work as a NAT gateway (but it's not working this way)
The loadbalancer has an external IP, inboundNatPool (which works), backendAddressPool (in which nodes are successfully registered)
the Network Security Group manages access to ports (set to allow all outbound connections)
As a footnote, I'm comfortable writing up AWS cloudformation files in YAML, so I'm handling Azure Resource Manager Templates in a similar way, for the sake of readability and the added functionality of adding comments in my template.
An Example of my vmss config (short snippet)
... #(yaml-template is first converted to json and than deployed using the azure cli)
# Cluster
# -------
# Scale Set
# ---------
# | VM Scale Set can not connect to external sources
# |
- type: Microsoft.Compute/virtualMachineScaleSets
name: '[variables(''vmssName'')]'
location: '[resourceGroup().location]'
apiVersion: '2017-12-01'
dependsOn:
- '[variables(''vnetName'')]'
- '[variables(''loadBalancerName'')]'
- '[variables(''networkSecurityGroupName'')]'
sku:
capacity: '[variables(''instanceCount'')]' # Amount of nodes to be spawned
name: Standard_A2_v2
tier: Standard
# zones: # If zone is specified, no sku can be chosen
# - '1'
properties:
overprovision: 'true'
upgradePolicy:
mode: Manual
virtualMachineProfile:
networkProfile:
networkInterfaceConfigurations:
- name: '[variables(''vmssNicName'')]'
properties:
ipConfigurations:
- name: '[variables(''ipConfigName'')]'
properties:
loadBalancerBackendAddressPools:
- id: '[variables(''lbBackendAddressPoolsId'')]'
loadBalancerInboundNatPools:
- id: '[variables(''lbInboundNatPoolsId'')]'
subnet:
id: '[variables(''subnetId'')]'
primary: true
networkSecurityGroup:
id: '[variables(''networkSecurityGroupId'')]'
osProfile:
computerNamePrefix: '[variables(''vmssName'')]'
adminUsername: '[parameters(''sshUserName'')]'
# adminPassword: '[parameters(''adminPassword'')]'
linuxConfiguration:
disablePasswordAuthentication: True
ssh:
publicKeys:
- keyData: '[parameters(''sshPublicKey'')]'
path: '[concat(''/home/'',parameters(''sshUserName''),''/.ssh/authorized_keys'')]'
storageProfile:
imageReference: '[variables(''clusterImageReference'')]'
osDisk:
caching: ReadWrite
createOption: FromImage
...
The Network Security Group referenced from the template above is:
# NetworkSecurityGroup
# --------------------
- type: Microsoft.Network/networkSecurityGroups
name: '[variables(''networkSecurityGroupName'')]'
apiVersion: '2017-10-01'
location: '[resourceGroup().location]'
properties:
securityRules:
- name: remoteConnection
properties:
priority: 101
access: Allow
direction: Inbound
protocol: Tcp
description: Allow SSH traffic
sourceAddressPrefix: '*'
sourcePortRange: '*'
destinationAddressPrefix: '*'
destinationPortRange: '22'
- name: allow_outbound_connections
properties:
description: This rule allows outbound connections
priority: 200
access: Allow
direction: Outbound
protocol: '*'
sourceAddressPrefix: 'VirtualNetwork'
sourcePortRange: '*'
destinationAddressPrefix: '*'
destinationPortRange: '*'
And the loadbalancer, where I assume the error should be, is described as:
# Loadbalancer as NatGateway
# --------------------------
- type: Microsoft.Network/loadBalancers
name: '[variables(''loadBalancerName'')]'
apiVersion: '2017-10-01'
location: '[resourceGroup().location]'
sku:
name: Standard
dependsOn:
- '[variables(''natIPAddressName'')]'
properties:
backendAddressPools:
- name: '[variables(''lbBackendPoolName'')]'
frontendIPConfigurations:
- name: LoadBalancerFrontEnd
properties:
publicIPAddress:
id: '[variables(''natIPAddressId'')]'
inboundNatPools:
- name: '[variables(''lbNatPoolName'')]'
properties:
backendPort: '22'
frontendIPConfiguration:
id: '[variables(''frontEndIPConfigID'')]'
frontendPortRangeStart: '50000'
frontendPortRangeEnd: '50099'
protocol: tcp
I keep reading articles about configuring a SNAT with port masquerading, but I'm missing relevant examples of such setup.
Any help is greatly appreciated.
It took a lot of searching but the article from Azure about Azure Load Balancer outbound Connections (Scenario #2) stated a load-balancing rule (and complementary Health Probe) was necessary for SNAT to function.
the new code for the load balancer became:
...
- type: Microsoft.Network/loadBalancers
name: '[variables(''loadBalancerName'')]'
apiVersion: '2017-10-01'
location: '[resourceGroup().location]'
sku:
name: Standard
dependsOn:
- '[variables(''natIPAddressName'')]'
properties:
backendAddressPools:
- name: '[variables(''lbBackendPoolName'')]'
frontendIPConfigurations:
- name: LoadBalancerFrontEnd
properties:
publicIPAddress:
id: '[variables(''natIPAddressId'')]'
probes: # Needed for loadBalancingRule to work
- name: '[variables(''lbProbeName'')]'
properties:
protocol: Tcp
port: 22
intervalInSeconds: 5
numberOfProbes: 2
loadBalancingRules: # Needed for SNAT to work
- name: '[concat(variables(''loadBalancerName''),''NatRule'')]'
properties:
disableOutboundSnat: false
frontendIPConfiguration:
id: '[variables(''frontEndIPConfigID'')]'
backendAddressPool:
id: '[variables(''lbBackendAddressPoolsId'')]'
probe:
id: '[variables(''lbProbeId'')]'
protocol: tcp
frontendPort: 80
backendPort: 80
...

Resources