How do I get container id from AWS CDK Mediastore? - amazon-web-services

How do I get container id from AWS CDK Mediastore?
It is being used as below code.
const mediaStoreContainer = new mediastore.CfnContainer(this, 'mediaStoreContainer', {
containerName: 'MediaStoreContainer',
accessLoggingEnabled: true,
})
I've tried many ways, but I can't find it.
mediaStoreContainer.getAtt(mediaStoreContainer.attrEndpoint)...
Please tell me how I can get it.

unfortunately, any time you have to use a Cfn function in CDK, this indicates that that resource/service/thing is not fully hooked into the cdk libraries. these Cfn functions simply are basic parsers that output a json structure for the cloudformation template. getAtt may not even be hooked into all the attributes available to a given item, and most of the time the Cfn versions of a construct can't even be passed to other constructs that would use them (such as having a Role created and passing that role to a Lambda to use)
getAtt just mimics the yaml macro function !getAttr and so can only retrieve what is available from the cloudformation entry for that resource
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-mediastore-container.html - this page indicates its just Endpoint - i believe all you need to use is endpoint = mediaStorecontainer.getAtt("Endpoint")

Related

Working with S3 buckets having no BucketName in AWS Lambda

Since the global uniqueness requirements of S3 bucket names, using the optional BucketName property in the AWS::S3::Bucket resource is problematic. Essentially, if I insist on using BucketName I need some way to attach a GUID there.
I can avoid this pain if I omit the BucketName property entirely, so CloudFormation reliably generates a unique name for me.
However, I face another problem: how do I work with this random bucket name in AWS Lambda/SAM/serverless.com/other code? I understand that CloudFormation templates can export the name, but how do I pass it to the Lambda code?
Is there a standard/recommended way of working with CloudFormation exports in AWS Lambda? The problem is not unique to S3 - e.g., AWS Amplify uses randomly generated DynamoDB table names, too.
If your Lambda is created through CloudFormation, you can pass the bucket name using Environment variables (Environment key in SAM and CloudFormation). You can refer to the bucket name using !Ref if the bucket is in the same spec and cross stack references if using different stacks. If you use cross stack references, you won't be able to modify or delete the output value in the original stack until you remove all references to it. If you are using Ref, the Lambda will also be updated if the bucket name changes.
If your Lambda isn't created through CloudFormation, you can use SSM parameter store as mentioned by Ervin in his comment. You can create a SSM Parameter and read it's value in your Lambda code.

Deploy Lambda Function using CodePipeline and CDK generated CloudFormation Template

I have a Lambda function that I'm trying to deploy using CodePipeline.
The Lambda function source code is in the same project as the Lambda CDK app. Since they are both in the same repository, the CDK app can reference the Lambda source code directly.
The docs suggest to use lambda.Code.fromAsset(path) when the CDK app can reference the Lambda code directly so I started with the follow definition for my Lambda function.
const fn = new lambda.Function(this, "Fn", {
code: lambda.Code.fromAsset(path/to/lambda/source),
handler: "index.handler",
runtime: lambda.Runtime.NODEJS_10_X
});
In the CodePipeline, I use CodeBuild to run cdk synth and synthesize the CloudFormation template.
The problem with defining my Lambda in this way is the CloudFormation template has parameters for the Lambda source code bucket and key which are seemingly named randomly e.g. AssetParameters3ffd...affdS3Bucket1CFF873D
When you run cdk deploy the CLI knows what the parameters are and populates them with values.
In my case however, I'm not using cdk deploy. I want to use CloudFormation in a CodePipeline.
That means I need to fill the parameters with the values for the Lambda source artifact which is output from my CodeBuild step. Getting the values is easy but I have no way of knowing what the parameters are named.
Next I tried using the following to define the parameter names myself.
const fn = new lambda.Function(this, "Fn", {
code: lambda.Code.fromCfnParameters({
bucketNameParam: new core_1.CfnParameter(this, "LambdaSourceBucket"),
objectKeyParam: new core_1.CfnParameter(this, "LambdaSourceKey"),
}),
handler: "index.handler",
runtime: lambda.Runtime.NODEJS_10_X
});
No luck. cdk synth still modifies the parameter names in the template e.g. AppLambdaSourceBucket8B89D730. That's better than before but I still can't be sure what the parameters will be named so I can assign them in my CodePipeline.
I can't use lambda.Code.fromBucket(bucket, key) because the bucket and key are determined by the CodePipeline/CodeBuild.
I found this example which is doing almost the same thing as me except their CodePipeline is defined in the same CDK app as their Lambda function. That avoids the problem that I'm having because the Lambda definition and CodePipeline definition can both reference the same CfnParametersCode instance.
Unfortunately I can't co-locate my CodePipeline definition with my Lambda like they've done in that example. I feel like this should still be possible without that.
What am I missing?
I'm able to do this with new CfnParametersCode (which should be equivalent to the factory method you're calling). Are you possibly creating this inside another construct and not at the stack level?

How to pass aws-lambda function name to generate a cloudwatch alarm using cloudformation template

I have an aws lambda function on top of which I am trying to create a cloudwatch alarm using cloudformation template.
Lets say I have a lambda function named MyPackage-MyLambdaFunctionName but when I see my lambda in the aws console, it says MyPackage-MyLambdaFunctionName-M2DEESRWNF6I.
I am able to create the alarm by passing the below in the dimensions:
Dimensions:
- Name: FunctionName
Value: MyPackage-MyLambdaFunctionName-M2DEESRWNF6I
(Referring to How to set lambda alarm for specific lambda using CloudFormation)
But the issue is the lambda function is having a random component at the end (-M2DEESRWNF6I).
I have a cloudformation template which goes in a few accounts and creates these lambda functions. And since these random identifiers are different in each account, I cant put the above in cloudformation template, since it will work for one account but not for the others.
So, how can I achieve creating these cloudwatch alarms on my lamdba functions using the cloudformation template?
such as does "Value" takes regex? I tried
MyPackage-MyLambdaFunctionName.*
which didnt work. Or is there a way to restrict the lambda function name to be just MyPackage-MyLambdaFunctionName (without the random identifier)
Any guidance/help is appreciated.
Thanks
The random string on the end of your lambda's function name is there because you're not setting the lambda name explicitly when it's created. From docs:
FunctionName
The name of the Lambda function, up to 64 characters in
length. If you don't specify a name, AWS CloudFormation generates one.
In general, this is correct thing to do because if you do set it, you can't change any of the parameters that require replacement (I can't think of any parameters that require that on lambda though).
From the same doc:
If you specify a name, you cannot perform updates that require
replacement of this resource. You can perform updates that require no
or some interruption. If you must replace the resource, specify a new
name.
To create the alarm you can just reference the Lambda function in the alarm creation code.
Like this:
Dimensions:
- Name: "FunctionName"
Value:
Ref: LambdaFunctionReference

How can I pass a repository resource in as a parameter to AWS codepipeline template?

I have a yml cloudformation template (A) for an AWS codepipeline build that I want to make a variation of it in an another template (B).
The original (A) has a repository as one of its resources which it created when initially run thru cloudformation. I'd like the variation (B) template to use the same ECR repository generated in the original (A), for the codebuild.
Is there a way I can have (B) template use the ECR resource created in A by passing in the repository resource value as a parameter or something?
For example the resource in A that I want to reuse (not recreate) in B is something like :
Repository:
Type: AWS::ECR::Repository
Properties:
RepositoryName: !Sub comp/${ServiceName}
RepositoryPolicyText:
Version: 2012-10-17
Statement:
...
I am not sure from your question what resources you are referring to. But in general you can export any value from one stack into another, using the Export property of the Output section
From Exporting Stack Output Values
To share information between stacks, export a stack's output values.
Other stacks that are in the same AWS account and region can import
the exported values. For example, you might have a single networking
stack that exports the IDs of a subnet and security group for public
web servers. Stacks with a public web server can easily import those
networking resources. You don't need to hard code resource IDs in the
stack's template or pass IDs as input parameters.

AWS SSM Parameter Store with CloudFormation

From the CFN docs I can see that I can create an AWS::SSM::Parameter. I also see how I can create a KMS Master Key.
However the type parameter on the SSM:Parameter in the doc page does not list the secure string type.
Is there a way that I can do the following in a cloudformation template:
1) create KMS Key
2) use KMS key to encrypt a param
3) pull that param in User-Data for an EC2 instance
I will be running the CFN template from a Jenkins job with the value of the param in a jenkins password parameter. I can also set "NoEcho": true on the template's parameter so it's not echoed in the CloudFormation console.
Support for this has been added so you no longer need to use a custom resource. You have to use a dynamic reference to a secure parameter.
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/dynamic-references.html
Using this feature you can use add {{resolve:ssm-secure:parameter-name:version}} to your user data within a Fn::Join CF intrinsic.
As of April 2019 secure strings are not available as a parameter type in cloudformation templates however the documentation states that CloudFormation will support the Parameter Store ‘SecureString’ type in a later release.
https://aws.amazon.com/blogs/mt/integrating-aws-cloudformation-with-aws-systems-manager-parameter-store/
There seems to be a way to use a custom resource to do this. In combination with a lambda function.