Reference Secrets Manager Parameters to Secret String - amazon-web-services

Is there any way to reference parameters in SecretString field in Secrets Manager via CloudFormation?
The way I made the script, the !Ref parameter is a text and not a reference to the parameter.
AWSTemplateFormatVersion: 2010-09-09
Parameters:
Name:
Type: String
myuserparameter:
Type: String
mypasswordparameter:
Type: String
Resources:
SecretsManager:
Type: AWS::SecretsManager::Secret
Properties:
Name: !Ref Name
SecretString: '{"username":"!Ref myuserparameter,"password":"Ref mypasswordparameter"}'

this will work:
AWSTemplateFormatVersion: 2010-09-09
Parameters:
Name:
Type: String
myuserparameter:
Type: String
mypasswordparameter:
Type: String
Resources:
SecretsManager:
Type: AWS::SecretsManager::Secret
Properties:
Name: !Ref Name
SecretString: !Sub '{"username": "${myuserparameter}","password": "${mypasswordparameter}"}'

Related

how to put the lambda in VPC by CloudFormation template

I am developping lambda with CloudFormation by SAM
My template.yaml is here.
It can be deployed, however this lambda is not set in VPC.
I want to put the lambda in default VPC (to access RDS)
Any setting can be used here or I should do something another??
(And, template makes IAmRole automatically, is there any way I can attach policy to it?? for example RDSFullAccess)
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
python3.9 Sample SAM Template for chatbot-sam
Parameters:
DBNAME:
Type: String
DBUSER:
Type: String
DBPASSWORD:
Type: String
DBHOST:
Type: String
DBPORT:
Type: String
LINELONGLIVETOKEN:
Type: String
Globals:
Function:
Timeout: 30
Environment:
Variables:
DBNAME: !Ref DBNAME
DBUSER: !Ref DBUSER
DBPASSWORD: !Ref DBPASSWORD
DBHOST: !Ref DBHOST
DBPORT: !Ref DBPORT
LINELONGLIVETOKEN: !Ref LINELONGLIVETOKEN
Resources:
WebhookFunction:
Type: AWS::Serverless::Function
Properties:
PackageType: Image
Architectures:
- x86_64
Events:
Webhook:
Type: Api
Properties:
Path: /webhook
Method: post
Metadata:
Dockerfile: Dockerfile.webhook
DockerContext: ./chatbotapp
DockerTag: python3.9-v1
Outputs:
WebhookApi:
Description: "API Gateway endpoint URL for Prod stage for Hello World function"
Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/webhook/"
WebhookFunction:
Description: "Webhook Lambda Function ARN"
Value: !GetAtt WebhookFunction.Arn
WebhookFunctionIamRole:
Description: "Implicit IAM Role created for Webhook function"
Value: !GetAtt WebhookFunctionRole.Arn
I updated.
Attaches VpcConfig and Policies , however it doesn't look change.
lambda -> setting -> vpc, there is no vpc setting and can't find the clue it belongs to SecurityGroup and Subnet
Policies: AWSLambdaVPCAccessExecutionRole
VpcConfig:
SubnetIds:
- subnet-fb6fa4d0
- subnet-bf8ab8e4
SecurityGroupIds:
- sg-0641506b4ec3782de
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
python3.9 Sample SAM Template for chatbot-sam
Parameters:
DBNAME:
Type: String
DBUSER:
Type: String
DBPASSWORD:
Type: String
DBHOST:
Type: String
DBPORT:
Type: String
LINELONGLIVETOKEN:
Type: String
Globals:
Function:
Timeout: 30
Environment:
Variables:
DBNAME: !Ref DBNAME
DBUSER: !Ref DBUSER
DBPASSWORD: !Ref DBPASSWORD
DBHOST: !Ref DBHOST
DBPORT: !Ref DBPORT
LINELONGLIVETOKEN: !Ref LINELONGLIVETOKEN
Resources:
WebhookFunction:
Type: AWS::Serverless::Function
Properties:
PackageType: Image
Architectures:
- x86_64
Events:
Webhook:
Type: Api
Properties:
Path: /webhook
Method: post
Policies: AWSLambdaVPCAccessExecutionRole
VpcConfig:
SubnetIds:
- subnet-fb6fa4d0
- subnet-bf8ab8e4
SecurityGroupIds:
- sg-0641506b4ec3782de
Metadata:
Dockerfile: Dockerfile.webhook
DockerContext: ./chatbotapp
DockerTag: python3.9-v1
Outputs:
WebhookApi:
Description: "API Gateway endpoint URL for Prod stage for Hello World function"
Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/webhook/"
WebhookFunction:
Description: "Webhook Lambda Function ARN"
Value: !GetAtt WebhookFunction.Arn
WebhookFunctionIamRole:
Description: "Implicit IAM Role created for Webhook function"
Value: !GetAtt WebhookFunctionRole.Arn
You'll need to add a VpcConfig to the properties of your function definition. You can see an example of how to use that here.
You can also add policies to the default role that is made for the function, or you can supply your own role, in which case the default role will not be created.

Passing values from parent stack to nested stack for Cloudformation

I am new to nested stack and i am trying to pass input parameters from parent to child template. My parent stack looks like below:
AWSTemplateFormatVersion: "2010-09-09"
Transform: 'AWS::Serverless-2016-10-31'
Description: "ParentStack with all child stack"
Parameters:
AccountName:
Description: Please Enter valid Account Name.
Type: "CommaDelimitedList"
Default: "citi"
Region:
Description: Enter Region
Type: "CommaDelimitedList"
Default: "us-east-2"
S3BucketName:
Type: "CommaDelimitedList"
Default: ""
S3KeyName:
Type: "CommaDelimitedList"
Default: "Test-LambdaFunction.zip"
Resources:
LambdaStack1:
Type: "AWS::CloudFormation::Stack"
Properties:
Parameters:
TemplateURL: https://test272t3.s3.us-east-2.amazonaws.com/CFTemplates/lambda.yaml
CodeUri:
Bucket: Fn:Join [ ' ', [!Ref S3BucketName] ]
Key: Fn::Join [ ' ', [!Ref S3KeyName] ]
S3Stack:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: https://test272t3.s3.us-east-2.amazonaws.com/CFTemplates/s3child.yaml
Parameters:
BucketName: <<not sure how !sub can be paased in parent stack>>
AccessControl: PublicReadWrite
VersioningConfiguration:
Status: Suspended
And part of child template is as follows:
Parameters:
AccountName:
Description: Please Enter valid Account Name.
Type: String
Default: citi
Region:
Description: Enter Region
Type: String
Default: us-east-2
S3BucketName:
Type: "String"
Default: ""
S3KeyName:
Type: "String"
Default: "MeghFlow-DBConnMgmt-Lambda-DBConnMgmtFunction.zip"
testLambda:
Type: AWS::Serverless::Function
Properties:
CodeUri:
Bucket: !Ref S3BucketName
Key: !Ref S3KeyName
Handler: com.testff.testinghand.dbconnmgmt.lambda.testLambda::handleRequest
Runtime: java8
MemorySize: 1024
Policies: AmazonDynamoDBFullAccess
Environment:
Variables:
REGION: us-east-2
DYNAMODB_NAME: DBConnectionInfo
ArtifactBucket:
Type: AWS::S3::Bucket
DeletionPolicy: Delete
Properties:
BucketName: !Sub ${AccountName}-${Region}-artifacts
AccessControl: PublicReadWrite
VersioningConfiguration:
Status: Suspended
Issue: I am not quite sure how the input parameters can be passed from parent to child. I referred few links like but i was confused even more as to when the input type must be CommaDelimitedList vs string. I even tried keeping the param type to string in both parent and child but still i get below error:
"Value of property Parameters must be an object with String (or simple type) properties"
and on using Fn::join get error as below:
"Fn::Join object requires two parameters, (1) a string delimiter and (2) a list of strings to be joined or a function that returns a list of strings (such as Fn::GetAZs) to be joined."
Have referred link : Trying to pass parameters from Master to child template but no luck .
Can anyone guide me in correct direction please. Thanks in advance.
Thanks #gandaliter for your guidance. As per above marked answer CloudFormation parent stack accepts only strings and not any object level parameters(sub parameters under parameters just like CodeURI in my above code). I did few tweaks and changed all the parent template to below :
Note: All the parameter type are set to String in child and parent template
AWSTemplateFormatVersion: "2010-09-09"
Transform: 'AWS::Serverless-2016-10-31'
Description: "ParentStack with all child stack"
Parameters:
apiGatewayStageName:
Type: String
Default: "dev"
HandlerName:
Type: String
Default: "com.test.tehgsaLambda::handleRequest"
S3BucketName:
Type: String
Default: ""
S3KeyName:
Type: String
Default: "Test-LambdaFunction.zip"
Resources:
LambdaStack1:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL:
Fn::Sub: "https://testyu2y73.s3.us-east-2.amazonaws.com/CFTemplates/lambda.yaml"
Parameters:
S3BucketName: !Ref S3BucketName
S3KeyName: !Ref S3KeyName
HandlerName: !Ref HandlerName
apiGatewayStageName: !Ref apiGatewayStageName
```
I imagine the code you've given above isn't the only combination you've tried, and the parameters don't exactly line up between your parent and child stack, but in any case, the problem is that you're trying to give parameter values of:
CodeUri:
Bucket: Fn:Join [ ' ', [!Ref S3BucketName] ]
Key: Fn::Join [ ' ', [!Ref S3KeyName] ]
and
VersioningConfiguration:
Status: Suspended
Both of these are objects, not 'String (or simple type) properties'. The error is saying that the whole Parameters object must have only simple values.
Incidentally, TemplateURL needs to go outside the Parameters object.

Value of property Parameters must be an object with String (or simple type) properties

I am trying to pass parameters to one of the nested stacks by populating the values from another nested stacks output.
And i do not want any cross-referencing (unless there is no way around it)
The idea is pretty straight forward.
RootStack
-NstdStackVPC
-NstdStackSG
-NstdStackEC2
The problem is on the last nested stack while creating EC2.
If i created the resource in the root stack directly the EC2 gets created
Description: RootStack
Parameters:
MyKeyName:
Type: AWS::EC2::KeyPair::KeyName
Default: my-test-key
EC2ImageId:
Type: AWS::EC2::Image::Id
Default: ami-0dxxxxa
Resources:
NstdStackVPC ......
NstdStackSG ......
EC2Host:
Type: AWS::EC2::Instance
Properties:
SubnetId: !GetAtt NstdStackVPC.Outputs.VPCPubSubnet
ImageId: !Ref EC2ImageId
InstanceType: t2.micro
KeyName: !Ref MyKeyName
SecurityGroupIds:
- !GetAtt NstdStackSG.Outputs.SecGrp4EC2Host
But if i try to create the EC2 as a nested stack
AWSTemplateFormatVersion: '2010-09-09'
Description: NstdStackEC2.
Parameters:
myNstdKeyName:
Type: AWS::EC2::KeyPair::KeyName
myNstdImageId:
Type: AWS::EC2::Image::Id
myNstdSecGrp:
Type: AWS::EC2::SecurityGroup::Id
myNstdEC2HostSubnet:
Type: AWS::EC2::Subnet::Id
Resources:
EC2Host:
Type: AWS::EC2::Instance
Properties:
SubnetId: !Ref myNstdEC2HostSubnet
ImageId: !Ref myNstdImageId
InstanceType: t2.micro
KeyName: !Ref myNstdKeyName
SecurityGroupIds:
- Ref myNstdSecGrp
By changing the root stack as follows
AWSTemplateFormatVersion: '2010-09-09'
Description: RootStack
Parameters:
MyKeyName:
Type: AWS::EC2::KeyPair::KeyName
Default: my-test-key
EC2ImageId:
Type: AWS::EC2::Image::Id
Default: ami-0dxxxxa
Resources:
NstdStackVPC ......
NstdStackSG ......
NstdStackEC2:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: https://bkt.s3.eu-central-1.amazonaws.com/NstdEC2Host.yml
Parameters:
myNstdKeyName: !Ref MyKeyName
myNstdImageId: !Ref EC2ImageId
myNstdSecGrp: !GetAtt NstdStackSG.Outputs.SecGrp4BasHost
myNstdEC2HostSubnet: !GetAtt NstdStackVPC.Outputs.VPCPubSubnet
It gives me the following error:
Value of property Parameters must be an object with String (or simple type) properties
tried removing all the parameters to try one by one. But it fails on everything.
Even for the parameters that are being referenced directly from the root stack i.e., MyKeyName, EC2ImageId
I ran into the same exact error message with a similar problem and solution. I came here and since the issue was slightly different, this question helped me get to my solution. So, not trying to hijack this question, simply hoping to provide what I found additionally useful to the next person visiting.
I was nesting a cluster template very similar to this one and OPs example. Passing Subnets as a list of strings (I believe List<AWS::Some::Type> will also work).
Subnets:
Description: Subnets of the of the cluster availaibility zone
Type: CommaDelimitedList
Default: subnet-0d..de,subnet-0e..7a,subnet-0b..24
And I'm using the above parameters to call the partial child template as follows.
ECS:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: https://xx.amazonaws.com/yy/zz.yaml
Parameters:
SecurityGroups: !Join [",", [!GetAtt SecurityGroups.Outputs.ECSHostSecurityGroup]]
Subnets: !Join [",", !Ref Subnets]
So, In the above example, the SecurityGroups are joined together into a list from the output of the SecurityGroup Nested Template, but the subnets are simply joined together from the comma delimited parameter. There is a knowledge-center article too, if you want more info. TA OP
Ok finally sorted this out myself.
In my NstdStackSG outputs section i was referring to the object itself.
And that is where this goes wrong.
AWSTemplateFormatVersion: 2010-09-09
Description: Security group nested stack
Resources:
MySecGrp
Type: ....
.....
....
Outputs:
MyOtptSecGrp:
#This one is working for me.
Value: !GetAtt MySecGrp.GroupId
#previously i was assigning the following value
#Value: !Re MySecGrp
And now in the RootStack
AWSTemplateFormatVersion: '2010-09-09'
Description: RootStack
Parameters:
MyKeyName:
Type: AWS::EC2::KeyPair::KeyName
Default: my-test-key
EC2ImageId:
Type: AWS::EC2::Image::Id
Default: ami-0dxxxxa
Resources:
NstdStackVPC ......
NstdStackSG ......
NstdStackEC2:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: https://bkt.s3.eu-central-1.amazonaws.com/NstdEC2Host.yml
Parameters:
myNstdKeyName: !Ref MyKeyName
myNstdImageId: !Ref EC2ImageId
myNstdSecGrp: !GetAtt NstdStackSG.Outputs.SecGrp4BasHost
myNstdEC2HostSubnet: !GetAtt NstdStackVPC.Outputs.VPCPubSubnet
And in my nestedEC2Stack
AWSTemplateFormatVersion: 2010-09-09
Description: NstdStackEC2
Parameters:
myNstdSecGrp:
Type: AWS::EC2::SecurityGroup::Id
myNstdEC2HostSubnet:
Type: AWS::EC2::Subnet::Id
myNstdKeyName:
Type: AWS::EC2::KeyPair::KeyName
myNstdImageId:
Type: AWS::EC2::Image::Id
Resources:
EC2Host:
Type: AWS::EC2::Instance
Properties:
SubnetId: !Ref myNstdEC2HostSubnet
ImageId: !Ref myNstdImageId
InstanceType: t2.micro
KeyName: !Ref myNstdKeyName
SecurityGroupIds:
- !Ref myNstdSecGrp
Hope this helps. (If not in solving then at least in pointing the right direction)

Use SSM parameter whose name depends on a CFN parameter

I have a CloudFormation template that looks something like the following:
AWSTemplateFormatVersion: '2010-09-09'
Parameters:
env:
Type: String
Default: NONE
Resources:
GraphQLAPI:
Type: AWS::AppSync::GraphQLApi
Properties:
Name: !Sub 'my-api-${env}'
AuthenticationType: AMAZON_COGNITO_USER_POOLS
UserPoolConfig:
UserPoolId: <something>
AwsRegion: !Ref AWS::Region
DefaultAction: ALLOW
Suppose that I already have a SSM parameter named /dev/cognitoUserPoolId. When I create this template, passing env=dev, I want to use the value of that parameter as the UserPoolId. I want to avoid manually passing a new CFN parameter for every SSM parameter, as there may be quite a few in practice.
You should be able to use dynamic references to the SSM parameters in your template.
Something like:
AWSTemplateFormatVersion: '2010-09-09'
Parameters:
env:
Type: String
Default: NONE
Resources:
GraphQLAPI:
Type: AWS::AppSync::GraphQLApi
Properties:
Name: !Sub 'my-api-${env}'
AuthenticationType: AMAZON_COGNITO_USER_POOLS
UserPoolConfig:
UserPoolId: !Sub '{{resolve:ssm:/${env}/cognitoUserPoolId:1}}'
AwsRegion: !Ref AWS::Region
DefaultAction: ALLOW
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/dynamic-references.html

AWS Cloudformation nested stack parameter type for parameter name does not exist

I'm trying to deploy a parent and nested stacks to AWS with cloudformation. The parent stack looks like this
AWSTemplateFormatVersion: '2010-09-09'
Parameters:
VPC:
Description: Choose which VPC the Lambda-functions should be deployed to
Type: AWS::EC2::VPC::Id
Default: vpc-sdjkfnsdjklfn
Subnets:
Description: Choose which subnets Lambda-functions should be deployed to
Type: CommaDelimitedList
Default: "subnet-sdoifno, subnet-sdofjnsdo"
SecurityGroup:
Description: Select the Security Group to use for the Lambda-functions
Type: AWS::EC2::SecurityGroup::Id
Default: sg-sdklfnsdkl
Role:
Description: Role for Lambda functions
Type: String
Default: arn:aws:iam::dlfksd:role/ssdfnsdo
Resources:
RestApi:
Type: AWS::ApiGateway::RestApi
Properties:
Name: "my-api"
Description: "SPP Lambda API"
Stack1:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: 'https://s3.amazonaws.com/bucket/template1.yml'
Parameters:
VPC: !Ref VPC
Subnets: !Join
- ','
- !Ref Subnets
SecurityGroup: !Ref SecurityGroup
Role: !Ref Role
RestApi: !Ref RestApi
ApiResourceParent: !GetAtt "RestApi.RootResourceId"
The child stack looks like this
AWSTemplateFormatVersion: '2010-09-09'
Parameters:
VPC:
Type: AWS::EC2::VPC::Id
Subnets:
Type: CommaDelimitedList
SecurityGroup:
Type: AWS::EC2::SecurityGroup::Id
Role:
Type: String
RestApi:
Type: AWS::ApiGateway::RestApi
ApiResourceParent:
Type: AWS::ApiGateway::Resource
Resources:
Fucntion:
Type: AWS::Lambda::Function
Properties:
Code:
S3Bucket: bucket
S3Key: node_lambdas.zip
Handler: Function.handler
Role: !Ref Role
Runtime: nodejs6.10
Timeout: 300
VpcConfig:
SecurityGroupIds:
- !Ref SecurityGroup
SubnetIds: !Ref Subnets
#Policies: AWSLambdaDynamoDBExecutionRole
Permission:
Type: AWS::Lambda::Permission
Properties:
Action: lambda:InvokeFunction
FunctionName: !GetAtt "Function.Arn"
Principal: "apigateway.amazonaws.com"
SourceArn: !Sub "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${RestApi}/*/*/*"
Resource:
Type: AWS::ApiGateway::Resource
Properties:
RestApiId: !Ref RestApi
ParentId: !Ref ApiResourceParent
PathPart: addadjustments
When I run aws cloudformation deploy --template-file parent-stack.yml --stack-name spp-lambda --region us-east-1 --capabilities CAPABILITY_IAM I get the following error
Embedded stack
arn:aws:cloudformation:us-east-1:771653148224:stack/spp-lambda-Stack1-97M9BLBUM3A5/4a454a50-c274-11e8-b49c-500c28903236
was not successfully created: Parameter validation failed: parameter
type AWS::ApiGateway::RestApi for parameter name RestApi does not
exist, parameter type AWS::ApiGateway::Resource for parameter name
ApiResourceParent does not exist
It doesn't complain about the parameters that are explicitly defined in the parent template. I want the parameters it is complaining about to be created and passed dynamically as I won't know the values before hand. What am I doing wrong?
Although some of the AWS resource type are supported as a cloudformation parameter type, it doesn't mean all resource type are supported.
You are trying to reference API gateway value as an AWS-specific parameter type, but it is not supported: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/parameters-section-structure.html#aws-specific-parameter-types
I believe using String as the type is sufficient.