Amplify get Hosting URL in lambda as environment variable - aws-lambda

I need the URL of Cloudfront distribution that I added with amplify cli as an environment variable.
Status:
I found how template variables are added in file "api-cloudformation-template.json" under my function config.
Desired Output variable from "hosting/S3AndCloudFront/template.json" is CloudFrontSecureURL.
So I added rows to lambda config file, like so:
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "Lambda resource stack creation using Amplify CLI",
"Parameters": {
...
"hostingS3AndCloudFrontHostingBucketName": { // working example
"Type": "String",
"Default": "hostingS3AndCloudFrontHostingBucketName"
},
"hostingS3AndCloudFrontCloudFrontSecureURL": { // my example
"Type": "String",
"Default": "hostingS3AndCloudFrontCloudFrontSecureURL"
},
},
"Resources": {
"LambdaFunction": {
"Type": "AWS::Lambda::Function",
"Metadata": {
"aws:asset:path": "./src",
"aws:asset:property": "Code"
},
"Properties": {
...
"Environment": {
"Variables": {
...
"HOSTING_S3ANDCLOUDFRONT_HOSTINGBUCKETNAME": {
"Ref": "hostingS3AndCloudFrontHostingBucketName"
},
"HOSTING_S3ANDCLOUDFRONT_CLOUDFRONTSECUREURL": {
"Ref": "hostingS3AndCloudFrontCloudFrontSecureURL"
}
}
},
}
}
....
},
....
}
I'm getting hostingS3AndCloudFrontCloudFrontSecureURL (default value) in process.env.HOSTING_S3ANDCLOUDFRONT_CLOUDFRONTSECUREURL after publishing function.

Try using the Outputs section of the template along with Fn::ImportValue function documentation HERE
CloudFront Stack:
{
...
"Outputs" : {
"CloudfrontDomainOutput" : {
"Description" : "The cloudfront domain",
"Value" : {
"Fn::GetAtt": [
"hostingS3AndCloudFrontCloudFrontSecureURL",
"DomainName"
]
},
"Export" : {
"Name" : {"Fn::Sub": "${AWS::StackName}-hostingS3AndCloudFrontCloudFrontSecureURL" }
}
}
}
Lambda Stack
{
...
"Environment": {
"Variables": {
"HOSTING_S3ANDCLOUDFRONT_HOSTINGBUCKETNAME": {
"Ref": "hostingS3AndCloudFrontHostingBucketName"
},
"HOSTING_S3ANDCLOUDFRONT_CLOUDFRONTSECUREURL": {
"Fn::ImportValue" : {"Fn::Sub" : "${CloudFront_Stack_Name}-hostingS3AndCloudFrontCloudFrontSecureURL"}
}
}
}
}

Related

Unable to start AWSFIS-Run-CPU-Stress

While running AWSFIS-Run-CPU-Stress i am getting below error:
Unable to start action, due to a platform mismatch between the specified document and the targeted instances. I am trying this in Windows EC2 instance
My Experiment script look like this(removed confidential server info):
{
"description": "Test CPU stress predefined SSM document",
"targets": {
"testInstance": {
"resourceType": "aws:ec2:instance",
"resourceArns": [
"arn:aws:ec2:region:123456789012:instance/instance_id"
],
"selectionMode": "ALL"
}
},
"actions": {
"runCpuStress": {
"actionId": "aws:ssm:send-command",
"parameters": {
"documentArn": "arn:aws:ssm:region::document/AWSFIS-Run-CPU-Stress",
"documentParameters": "{\"DurationSeconds\":\"120\"}",
"duration": "PT5M"
},
"targets": {
"Instances": "testInstance"
}
}
},
"stopConditions": [
{
"source": "aws:cloudwatch:alarm",
"value": "arn:aws:cloudwatch:region:123456789012:alarm:awsec2-instance_id-GreaterThanOrEqualToThreshold-CPUUtilization"
}
],
"roleArn": "arn:aws:iam::123456789012:role/AllowFISSSMActions",
"tags": {}
}

NLog: LayoutRenderer cannot be found: 'aspnet-user-identity

I try to implement NLog into my .NET Core Api web service.
I want to log to an Oracle database. All works well through an nlog.config XML file.
But the goal is to implement NLog config into appsettings.json and here problem occurs.
I get the error set in title:
LayoutRenderer cannot be found: 'aspnet-user-identity
My config file is like this :
"NLog": {
"autoReload": true,
"throwConfigExceptions": true,
"internalLogLevel": "info",
"internalLogFile": "c:/app/log/dev/internal-appsetting-nlog.txt",
"extensions": {
"NLog.Extensions.Logging": {
"assembly": [
"NLog.Extensions.Logging",
"NLog.Web.AspNetCore"
]
}
},
"variables": {
"var_logdir": "c:/app/log/dev"
},
"default-wrapper": {
"type": "AsyncWrapper",
"overflowAction": "Block"
},
"targets": {
"all-file": {
"type": "File",
"fileName": "${var_logdir}/nlog-all-${shortdate}.log",
"layout": {
"type": "JsonLayout",
"Attributes": [
{
"name": "timestamp",
"layout": "${date:format=o}"
},
{
"name": "level",
"layout": "${level}"
},
{
"name": "logger",
"layout": "${logger}"
},
{
"name": "message",
"layout": "${message:raw=true}"
},
{
"name": "properties",
"encode": false,
"layout": {
"type": "JsonLayout",
"includeallproperties": "true"
}
}
]
}
},
"db": {
"type": "Database",
"commandText": "INSERT INTO logtable (LOGLEVEL,LOGGER,MESSAGE,MACHINENAME,USERNAME,CALLSITE, THREADID,EXCEPTIONMESSAGE,STACKTRACE,SESSIONID) VALUES (:pLEVEL,:pLOGGER,:pMESSAGE,:pMACHINENAME, :pCALLSITE,:pTHREADID,:pEXCEPTIONMESSAGE,:pSTACKTRACE)",
"parameters": [
{
"name": "#pLEVEL",
"layout": "${level}"
},
{
"name": "#pLOGGER",
"layout": "${logger}"
},
{
"name": "#pMESSAGE",
"layout": "${message}"
},
{
"name": "#pMACHINENAME",
"layout": "${machinename}"
},
{
"name": "#pUSERNAME",
"layout": "${aspnet-user-identity}"
},
{
"name": "#pCALLSITE",
"layout": "${callsite:filename=true}"
},
{
"name": "#pTHREADID",
"layout": "${threadid}"
},
{
"name": "#pEXCEPTIONMESSAGE",
"layout": "${exception}"
},
{
"name": "#pSTACKTRACE",
"layout": "${stacktrace}"
},
{
"name": "#pSESSIONID",
"layout": "${aspnet-sessionid}"
}
],
"dbProvider": "Oracle.ManagedDataAccess.Client.OracleConnection, Oracle.ManagedDataAccess",
"connectionString": "xxxxxxxxxxxx"
}
},
"rules": [
{
"logger": "*",
"minLevel": "Trace",
"writeTo": "all-file"
},
{
"logger": "*",
"minLevel": "Trace",
"writeTo": "db"
},
{
"logger": "Microsoft.*",
"maxLevel": "Info",
"final": true
}
]
},
The internal debugger reports:
2019-10-09 16:48:48.6665 Info Adding target AsyncTargetWrapper(Name=all-file)
2019-10-09 16:48:48.7859 Warn Error when setting property 'Layout' on 'NLog.Targets.DatabaseParameterInfo' Exception: System.ArgumentException: LayoutRenderer cannot be found: 'aspnet-user-identity'. Is NLog.Web not included?
at NLog.Config.Factory`2.CreateInstance(String itemName)
at NLog.Layouts.LayoutParser.GetLayoutRenderer(ConfigurationItemFactory configurationItemFactory, String name)
at NLog.Layouts.LayoutParser.ParseLayoutRenderer(ConfigurationItemFactory configurationItemFactory, SimpleStringReader stringReader)
at NLog.Layouts.LayoutParser.CompileLayout(ConfigurationItemFactory configurationItemFactory, SimpleStringReader sr, Boolean isNested, String& text)
at NLog.Layouts.SimpleLayout.set_Text(String value)
at NLog.Internal.PropertyHelper.TryNLogSpecificConversion(Type propertyType, String value, Object& newValue, ConfigurationItemFactory configurationItemFactory)
at NLog.Internal.PropertyHelper.SetPropertyFromString(Object obj, String propertyName, String value, ConfigurationItemFactory configurationItemFactory)
Error occurs on ${aspnet-sessionid}. If I comment out both layout, everything works well.
I found different things on GitHub issue report but all I tried was a fail.
Could someone help?
The unknown aspnet-user-identity is probably an issue with your extensions:
"extensions": [
{ "assembly": "NLog.Extensions.Logging" },
{ "assembly": "NLog.Web.AspNetCore" }
],
Could you try the above suggestion?
P.S. Updated the wiki to include example of multiple "extensions"

Fabric SDK unable to initialize cryptosuite config

I'm running a business network on IBM Cloud Blockchain Platform 2.0. I downloaded a connection profile from the instantiated smart contracts section on the Platform Console, and am trying to connect using the Fabric SDK for Go but I am facing an error.
This is my current relevant code, under main
configOpts := fabricConfig.FromFile("./profiles/flex.json")
fabSDK, err := fabsdk.New(configOpts)
if err != nil {
entry.WithError(err).Fatal("Error setting up Fabric SDK")
}
defer fabSDK.Close()
Expected: Connects to the business network instance
Actual: I get an error
FATA[0000] Error setting up Fabric SDK env=DEV
error="failed to initialize configuration: unable to initialize cryptosuite using crypto suite config:
failed to initialize crypto suite: Unsupported BCCSP Provider: "
I add "cryptoconfig" path to the client.
BCCSP is optional, and you can remove.
I added the sample config, please see below.
More detail config at Github go-SDK config.yaml
{
"name": "first-network-org1",
"version": "1.0.0",
"client": {
"organization": "Org1",
"logging": {
"level": "info"
},
"cryptoconfig": {
"path": "crypto-config"
},
"credentialStore": {
"path": "/tmp/keystore",
"cryptoStore": {
"path": "/tmp/msp"
}
},
"connection": {
"timeout": {
"peer": {
"endorser": "300"
}
}
}
},
"channels": {
"mychannel": {
"peers": {
"peer0.org1.example.com": {}
}
}
},
"orderers": {
"orderer.example.com": {
"url": "orderer.example.com:7050",
"grpcOptions": {
"ssl-target-name-override": "orderer.example.com",
"keep-alive-time": "60s",
"keep-alive-timeout": "60s",
"keep-alive-permit": false,
"fail-fast": false,
"allow-insecure": false
},
"tlsCACerts": {
"path": "crypto-config/ordererOrganizations/example.com/tlsca/tlsca.example.com-cert.pem"
}
}
},
"organizations": {
"Org1": {
"mspid": "Org1MSP",
"cryptoPath": "crypto-config/peerOrganizations/org1.example.com/users/User1#org1.example.com/msp",
"peers": [
"peer0.org1.example.com",
"peer1.org1.example.com"
],
"certificateAuthorities": [
"ca.org1.example.com"
]
}
},
"peers": {
"peer0.org1.example.com": {
"url": "grpcs://localhost:7051",
"tlsCACerts": {
"path": "crypto-config/peerOrganizations/org1.example.com/tlsca/tlsca.org1.example.com-cert.pem"
},
"grpcOptions": {
"ssl-target-name-override": "peer0.org1.example.com"
}
},
"peer1.org1.example.com": {
"url": "grpcs://localhost:8051",
"tlsCACerts": {
"path": "crypto-config/peerOrganizations/org1.example.com/tlsca/tlsca.org1.example.com-cert.pem"
},
"grpcOptions": {
"ssl-target-name-override": "peer1.org1.example.com"
}
}
},
"certificateAuthorities": {
"ca.org1.example.com": {
"url": "https://localhost:7054",
"caName": "ca-org1",
"tlsCACerts": {
"path": "crypto-config/peerOrganizations/org1.example.com/tlsca/tlsca.org1.example.com-cert.pem"
},
"httpOptions": {
"verify": false
}
}
}
}

Swagger use a custom swagger.json file aspnet core

Pretty sure I am missing something clearly obvious but not seeing it.
How can I use my updated swagger.json file?
I took my boilerplate swagger/v1/swagger.json code and pasted it into the editor.swagger.io system. I then updated the descriptions etc, added examples to my models and then saved the contents as swagger.json.
Moved the file into the root of my api application, set the file to copy always.
public void ConfigureServices(IServiceCollection services)
{...
services.AddSwaggerGen(c => { c.SwaggerDoc("V1", new Info {Title = "Decrypto", Version = "0.0"}); });
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
...
app.UseSwagger();
//--the default works fine
// app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/V1/swagger.json", "Decrypto v1"); });
app.UseSwaggerUI(c => { c.SwaggerEndpoint("swagger.json", "Decrypto v1"); });
app.UseMvc();
}
I have tried a few different variation but none seem to be the trick. I don't really want to rewrite the work in SwaggerDoc as it seems dirty to me put documentation in the runtime.
the custom swagger.json file I want to use looks like this:
{
"swagger": "2.0",
"info": {
"version": "0.0",
"title": "My Title"
},
"paths": {
"/api/Decryption": {
"post": {
"tags": [
"API for taking encrypted values and getting the decrypted values back"
],
"summary": "",
"description": "",
"operationId": "Post",
"consumes": [
"application/json-patch+json",
"application/json",
"text/json",
"application/*+json"
],
"produces": [
"text/plain",
"application/json",
"text/json"
],
"parameters": [
{
"name": "units",
"in": "body",
"required": true,
"schema": {
"uniqueItems": false,
"type": "array",
"items": {
"$ref": "#/definitions/EncryptedUnit"
}
}
}
],
"responses": {
"200": {
"description": "Success",
"schema": {
"uniqueItems": false,
"type": "array",
"items": {
"$ref": "#/definitions/DecryptedUnit"
}
}
}
}
}
}
},
"definitions": {
"EncryptedUnit": {
"type": "object",
"properties": {
"value": {
"type": "string",
"example": "7OjLFw=="
},
"initializeVector": {
"type": "string",
"example": "5YVg="
},
"cipherText": {
"type": "string",
"example": "596F5AA48A882"
}
}
},
"DecryptedUnit": {
"type": "object",
"properties": {
"encrypted": {
"type": "string",
"example": "7OjLV="
},
"decrypted": {
"type": "string",
"example": "555-55-5555"
}
}
}
}
}
you need to configure PhysicalFileProvider and put your swagger.json into wwwroot or anywhere accessible by PhysicalFileProvider. After that you can access it using IFileProvider
Reference: https://www.c-sharpcorner.com/article/file-providers-in-asp-net-core/
Edit If you just add app.UseStaticFiles(); into your StartUp, you can access wwwroot without hastle.
Reference
Completely Different Approach
you may also consider to serve your file using Controller/Action
public IActionResult GetSwaggerDoc()
{
var file = Path.Combine(Directory.GetCurrentDirectory(),
"MyStaticFiles", "swagger.json");
return PhysicalFile(file, "application/json");
}
.NET Core 2.2 could server physical file to url resource like below.
But if you use custom swagger json, your api is fixed except you change it every time.
public void Configure(IApplicationBuilder app, IHostingEnvironment env,
ILoggerFactory loggerFactory)
{
...
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(Directory.GetCurrentDirectory(),
"swagger/v1/swagger.json")),
RequestPath = "swagger/v1/swagger.json"
});
}

How to add cognito user pool authorizer to Lambda Proxy integration in Cloud Formation Template?

I have the following cloud formation JSON template. This template is the default template provided by AWS for C#(Dotnet) Web API Lambda proxy integration.
{
"AWSTemplateFormatVersion" : "2010-09-09",
"Transform" : "AWS::Serverless-2016-10-31",
"Description" : "An AWS Serverless Application that uses the ASP.NET Core framework running in Amazon Lambda.",
"Parameters" : {
"ShouldCreateBucket" : {
"Type" : "String",
"AllowedValues" : ["true", "false"],
"Description" : "If true then the S3 bucket that will be proxied will be created with the CloudFormation stack."
},
"BucketName" : {
"Type" : "String",
"Description" : "Name of S3 bucket that will be proxied. If left blank a new table will be created.",
"MinLength" : "0"
}
},
"Conditions" : {
"CreateS3Bucket" : {"Fn::Equals" : [{"Ref" : "ShouldCreateBucket"}, "true"]},
"BucketNameGenerated" : {"Fn::Equals" : [{"Ref" : "BucketName"}, ""]}
},
"Resources" : {
"ProxyFunction" : {
"Type" : "AWS::Serverless::Function",
"Properties": {
"Handler": "DotnetLanmada::DotnetLanmada.LambdaEntryPoint::FunctionHandlerAsync",
"Runtime": "dotnetcore2.0",
"CodeUri": "",
"MemorySize": 256,
"Timeout": 30,
"Role": null,
"Policies": [ "AWSLambdaFullAccess" ],
"Environment" : {
"Variables" : {
"AppS3Bucket" : { "Fn::If" : ["CreateS3Bucket", {"Ref":"Bucket"}, { "Ref" : "BucketName" } ] }
}
},
"Events": {
"PutResource": {
"Type": "Api",
"Properties": {
"Path": "/{proxy+}",
"Method": "ANY"
}
}
}
}
},
"Bucket" : {
"Type" : "AWS::S3::Bucket",
"Condition" : "CreateS3Bucket",
"Properties" : {
"BucketName" : { "Fn::If" : ["BucketNameGenerated", {"Ref" : "AWS::NoValue" }, { "Ref" : "BucketName" } ] }
}
}
},
"Outputs" : {
"S3ProxyBucket" : {
"Value" : { "Fn::If" : ["CreateS3Bucket", {"Ref":"Bucket"}, { "Ref" : "BucketName" } ] }
}
}
}
This template creates a Lambda function, API Gateway, and an S3 bucket. All the requests to API gateway are proxy-ed to the Lambda function. I want to authenticate all the requests to API gateway using an existing Cognito user pool. Basically, the API gateway will have a Cognito user pool authorizer and the proxy function is authorized with that. Since the API Gateway creation part is hidden in this template I have no clue how to add a Cognito user pool authorizer here.
Thanks in advance.
One way to achieve what you want is to export the ARN of your Lambda function, and then import it into your API Gateway stack.
To export your function's ARN, in your Outputs section add:
"Function": {
"Value": ProxyFunction.Arn,
"Export": {
"Name": "ProxyFunction::Arn"
}
}
You will also need to have an invocation permission for API Gateway to invoke your function. You can add something like this to your stack:
"LambdaInvocationPermission": {
"Type": "AWS::Lambda::Permission",
"Properties": {
"Action": "lambda:InvokeFunction",
"FunctionName": { "Fn::GetAtt" : [ "ProxyFunction", "Arn" ] },
"Principal": "apigateway.amazonaws.com"
}
}
Then in your API Gateway stack, you can reference your function's ARN with
{ "Fn::ImportValue" : "ProxyFunction::Arn" }

Resources