<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Kurt Feeley </title>
    <description>The latest articles on DEV Community by Kurt Feeley  (@kfeeley).</description>
    <link>https://dev.to/kfeeley</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F853795%2Fd352a77d-464a-4194-8f6a-2c085c7784cb.png</url>
      <title>DEV Community: Kurt Feeley </title>
      <link>https://dev.to/kfeeley</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kfeeley"/>
    <language>en</language>
    <item>
      <title>Find Source Code Vulnerabilities with CodeQL Before You Commit</title>
      <dc:creator>Kurt Feeley </dc:creator>
      <pubDate>Tue, 08 Aug 2023 02:09:16 +0000</pubDate>
      <link>https://dev.to/aws-builders/find-source-code-vulnerabilities-with-codeql-before-you-commit-2hof</link>
      <guid>https://dev.to/aws-builders/find-source-code-vulnerabilities-with-codeql-before-you-commit-2hof</guid>
      <description>&lt;p&gt;You have a plethora of Python code to commit for your new Django API. STOP! Before you commit and push, first scan your source code with the CodeQL CLI!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn5shny7yah69fbpw9to6.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn5shny7yah69fbpw9to6.jpg" alt="Insecure"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Photo by &lt;a href="https://unsplash.com/@imattsmart?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;iMattSmart&lt;/a&gt; on &lt;a href="https://unsplash.com/photos/Vp3oWLsPOss?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Solution
&lt;/h2&gt;

&lt;p&gt;In this tutorial, we’ll go over scanning Python source code for vulnerabilities in a development environment using the CodeQL CLI.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;p&gt;To complete this tutorial, you will need to install the CodeQL CLI.&lt;/p&gt;

&lt;h3&gt;
  
  
  Our Dev Environment
&lt;/h3&gt;

&lt;p&gt;This tutorial was developed using Ubuntu 22.10, Python 3.10.6, CodeQL CLI 2.13.1 and Visual Studio Code 1.78.2. Some commands/constructs may vary across platforms.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is CodeQL?
&lt;/h3&gt;

&lt;p&gt;CodeQL is a type of static application security testing (SAST) scanner that scans source code for vulnerabilities. A vulnerability is a weakness in an application that allows an attacker to cause harm to the application’s owner, the application users, and/or organizations that rely on the application, et. al. Popular attacks include: SQL injection, cross-site scripting and brute force attacks. Using a tool like CodeQL early in the development process can save time, money and possibly prevent damage to a company’s reputation.&lt;/p&gt;

&lt;h3&gt;
  
  
  1) Setup the CodeQL CLI
&lt;/h3&gt;



&lt;h4&gt;
  
  
  Download the CodeQL CLI
&lt;/h4&gt;

&lt;p&gt;Point your browser to the CodeQL releases page on GitHub and download the archive that corresponds to the platform that you are using. For this tutorial, we are downloading and using the release specified with “linux64” in the filename.&lt;/p&gt;

&lt;p&gt;CodeQL Releases: &lt;a href="https://github.com/github/codeql-cli-binaries/releases" rel="noopener noreferrer"&gt;https://github.com/github/codeql-cli-binaries/releases&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once the file has been downloaded, extract the files from the archive. For our Linux system, we’ll use the unzip command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ unzip codeql-linux64.zip -d ~/bin/codeql/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are going to take one more step and add the codeql executable to our PATH variable so that we can call “codeql” from any location within the OS. On our Ubuntu system we can accomplish this by modifying the PATH variable in the ~/.profile file by appending the path of the codeql executable.&lt;/p&gt;

&lt;h4&gt;
  
  
  Test the CodeQL CLI
&lt;/h4&gt;

&lt;p&gt;We can test the CodeQL CLI by checking the version at the command line.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ codeql ––version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If everything is setup correctly, We should see output something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CodeQL command-line toolchain release 2.13.1.
Copyright (C) 2019-2023 GitHub, Inc.
Unpacked in: /home/user/bin/codeql
Analysis results depend critically on separately distributed query and
extractor modules. To list modules that are visible to the toolchain,
use ‘codeql resolve qlpacks’ and ‘codeql resolve languages’.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can further test by using the following command to get a list of the languages that can be used.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ codeql resolve languages
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Download the CodeQL Language Packs
&lt;/h4&gt;

&lt;p&gt;To download precompiled queries for Python, use the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ codeql pack download codeql/python-queries
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2) Create the CodeQL Database
&lt;/h3&gt;

&lt;p&gt;Now that we have CodeQL downloaded and configured, we can create the CodeQL database.&lt;/p&gt;

&lt;h4&gt;
  
  
  Create a Directory for the CodeQL Database
&lt;/h4&gt;

&lt;p&gt;The first thing we will need to do is create a directory to house the CodeQL database.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mkdir ~/codeql-dbs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Create the CodeQL Database
&lt;/h4&gt;

&lt;p&gt;Now that we have a location for the database, let’s change to the directory of your app.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ cd ~/source/python-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we are set to create the CodeQL database with the following command:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Parameters:&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;~/codeql-dbs/python-app:&lt;/strong&gt; The CodeQL database location.&lt;br&gt;
&lt;strong&gt;language:&lt;/strong&gt; The language to scan. In this case, Python.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ codeql database create ~/codeql-dbs/python-app \
––language=python
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If everything goes to plan, the output of the database create command will end with something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;“Successfully created database at /home/user/codeql-dbs/python-app.”
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3) Scan the Source Code for Vulnerabilities
&lt;/h3&gt;

&lt;p&gt;With the CodeQL database created, we can start to scan our source code.&lt;/p&gt;

&lt;h4&gt;
  
  
  Create a Directory for the CodeQL Output
&lt;/h4&gt;

&lt;p&gt;CodeQL aggregates its findings in an output file. Let’s create a directory to house the output file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mkdir ./codeql-output/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Code Analysis
&lt;/h4&gt;

&lt;p&gt;Running the following command will instruct CodeQL to analyze the code using the previously built database for, “python-app.”&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Parameters:&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;~/codeql-dbs/python-app:&lt;/strong&gt; The CodeQL database location.&lt;br&gt;
&lt;strong&gt;format:&lt;/strong&gt; The output format. (Also supports SARIF and graph formats)&lt;br&gt;
&lt;strong&gt;output:&lt;/strong&gt; The path to the output file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ codeql database analyze ~/codeql-dbs/python-app \
––format=”csv” \
––output=”./codeql-output/scan.csv”
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When CodeQL completes its analysis, the console should display a message like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Shutting down query evaluator.
Interpreting results.
Analysis produced the following diagnostic data:
| Diagnostic | Summary |
+——————————+———–+
| Compilation message | 3 results |
| Successfully extracted files | 6 results |
Analysis produced the following metric data:
| Metric | Value |
+—————————————-+——–+
| Total lines of Python code in the database | 13,700 |
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;View the CodeQL Analysis Output&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ nano ./codeql-output/scan.csv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;p&gt;We have concluded this tutorial where you have learned how to scan Python source code for vulnerabilities in a development environment using the CodeQL CLI.&lt;/p&gt;

&lt;p&gt;Now, before you commit code for that Django API –– scan it for source code vulnerabilities with CodeQL before you commit.&lt;/p&gt;

</description>
      <category>python</category>
      <category>security</category>
      <category>tutorial</category>
      <category>shiftleft</category>
    </item>
    <item>
      <title>3 Things: Developing Amazon SQS Based Solutions</title>
      <dc:creator>Kurt Feeley </dc:creator>
      <pubDate>Mon, 12 Sep 2022 13:31:22 +0000</pubDate>
      <link>https://dev.to/aws-builders/3-things-developing-amazon-sqs-based-solutions-og4</link>
      <guid>https://dev.to/aws-builders/3-things-developing-amazon-sqs-based-solutions-og4</guid>
      <description>&lt;p&gt;Amazon Simple Queue Service or Amazon SQS is a distributed message queuing service that enables developers to build  loosely coupled solutions. Often valued for its ease of use, Amazon SQS queues can be spun up in a matter of seconds from the AWS console, SDK or the CLI.   Still, there are subtleties that developers should be aware of when developing solutions with Amazon SQS.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--eiGl1yT5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xuhpd93gxryqqbfgsrx4.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--eiGl1yT5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xuhpd93gxryqqbfgsrx4.jpg" alt="Image description" width="850" height="543"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Photo by &lt;a href="https://unsplash.com/@lsfineartphotography?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Shumilov Ludmila&lt;/a&gt; on &lt;a href="https://unsplash.com/?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Encryption
&lt;/h2&gt;

&lt;p&gt;Messages stored in an Amazon SQS queue is data at rest. And, we can protect that data by encrypting it with KMS keys, just like we would if we were going to protect data in an Amazon S3 bucket or an Amazon SNS topic. With Amazon SQS Server-side encryption with KMS, messages are encrypted when they are received by SQS and are decrypted when delivered to a message consumer that is authorized for the SQS message queue and the KMS key.&lt;/p&gt;

&lt;p&gt;Alternatively, Amazon Simple Queue Service provides it's own server-side encryption using SQS-managed encryption keys. Encrypting an SQS queue using SQS-managed encryption keys is as easy as using the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ aws sqs set-queue-attributes \
   ––queue-url https://(MyQueueURL) \
   ––attributes '{"SqsManagedSseEnabled": "true"}'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Temporal Messaging
&lt;/h2&gt;

&lt;p&gt;By default, messages that are stored in Amazon SQS are designed for "At-Least-Once Delivery". That is, an Amazon SQS message will be delivered at least once, but can be delivered more than once and there is no guarantee that the messages will stay ordered.  However, if you need messages delivered in order and only once, you may opt for Amazon SQS FIFO queues.  Amazon SQS FIFO queues are designed for, Exactly-Once Processing, where messages are only delivered once and are delivered in the order of, First-In-First-Out.&lt;/p&gt;

&lt;p&gt;Below is an example of sending a message to an Amazon SQS FIFO queue using the AWS .NET SDK. Note the use of the "MessageGroupId" property.  This is a requirement for FIFO messaging.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SendMessageRequest sendMessageRequest = new SendMessageRequest(queueUrl, message);

sendMessageRequest.MessageGroupId = "message-group-1";

var sqsClient = new AmazonSQSClient();

await sqsClient.SendMessageAsync(sendMessageRequest);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Message Retention
&lt;/h2&gt;

&lt;p&gt;Messages in Amazon SQS can not be stored forever.  In fact, messages in Amazon SQS can be stored for a maximum of 14 days and for as little as 1 minute.  By default, the Amazon SQS message retention period is a generous 4 days.&lt;/p&gt;

&lt;p&gt;The following is an example of a command for setting an Amazon SQS queue to have a retention period of 1 minute using the AWS CLI.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ aws sqs set-queue-attributes \
   ––queue-url https://(MyQueueURL) \
   ––attributes '{"MessageRetentionPeriod": "60'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Want to know more about the tech in this article?  Checkout these resources:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://aws.amazon.com/cli/"&gt;AWS CLI&lt;/a&gt;, &lt;a href="https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html"&gt;Configuring the AWS CLI&lt;/a&gt;, &lt;a href="https://aws.amazon.com/sdk-for-net/"&gt;AWS .NET SDK&lt;/a&gt;, &lt;a href="https://dotnet.microsoft.com/en-us/learn/dotnet/what-is-dotnet"&gt;.NET&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>serverless</category>
      <category>sqs</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Securing .NET App Secrets with AWS Secrets Manager</title>
      <dc:creator>Kurt Feeley </dc:creator>
      <pubDate>Thu, 02 Jun 2022 16:31:20 +0000</pubDate>
      <link>https://dev.to/aws-builders/securing-net-app-secrets-with-aws-secrets-manager-2f4h</link>
      <guid>https://dev.to/aws-builders/securing-net-app-secrets-with-aws-secrets-manager-2f4h</guid>
      <description>&lt;p&gt;AWS Systems Manager Parameter Store is a great all around addition to your configuration and secrets management story. &lt;a href="https://aws.amazon.com/systems-manager/pricing/#Parameter_Store" rel="noopener noreferrer"&gt;Parameter Store can be a cost effective solution&lt;/a&gt; as there isn't a charge for standard parameters. Parameter Store supports the storage of common configuration data like a URL (String Type) and data that's a bit more complex like a list of OAuth2 scopes (StringList Type) but, &lt;a href="https://aws.amazon.com/secrets-manager/" rel="noopener noreferrer"&gt;AWS Systems Manager Parameter Store&lt;/a&gt; also supports more sensitive configuration data like secrets, passwords and tokens (SecureString Type). &lt;/p&gt;

&lt;p&gt;So, why use AWS Secrets Manager? AWS Secrets Manager features automated secret rotation and direct integration with services like RDS, Redshift, and DocumentDB.  So, if you need to automatically rotate secrets or need integration with data storage technologies like RDS, Redshift, and DocumentDB, AWS Secrets Manager may be the right choice for you.&lt;/p&gt;

&lt;p&gt;In this post we’ll focus on AWS Secrets Manager, but if AWS Systems Manager Parameter Store sounds more like your thing, check out this post on &lt;a href="https://dev.to/aws-builders/use-aws-systems-manager-parameter-store-as-a-net-configuration-provider-1e68"&gt;Using AWS Systems Manager Parameter Store as a .NET Configuration Provider&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz5jjii10ztvkt3vda4yw.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz5jjii10ztvkt3vda4yw.jpg" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Photo by &lt;a href="https://unsplash.com/@saeedkarimi?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;saeed karimi&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/secret?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Solution
&lt;/h2&gt;

&lt;p&gt;In this article, we’ll take a look at using AWS Secrets Manager to store and retrieve confidential data. We’ll create a .NET API as the reference application and we'll use the AWS CLI and a .NET library developed by AWS that makes this process simple.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;p&gt;To complete this solution, you will need the &lt;a href="https://docs.microsoft.com/en-us/dotnet/core/tools/" rel="noopener noreferrer"&gt;.NET CLI&lt;/a&gt; which is included in the &lt;a href="https://dotnet.microsoft.com/download/visual-studio-sdks" rel="noopener noreferrer"&gt;.NET 6 SDK&lt;/a&gt;. In addition, you will need to download the &lt;a href="https://aws.amazon.com/cli/" rel="noopener noreferrer"&gt;AWS CLI&lt;/a&gt; and &lt;a href="https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html" rel="noopener noreferrer"&gt;configure your environment&lt;/a&gt; for the AWS CLI. You will also need to create an AWS IAM user with programmatic access with the appropriate permissions to create and read secrets in AWS Secrets Manager.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Warning: some AWS services may have fees associated with them.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The Dev Environment
&lt;/h3&gt;

&lt;p&gt;This tutorial was developed using Ubuntu 20.04, AWS CLI v2, .NET 6 SDK and Visual Studio Code 1.66.2. Some commands/constructs may very across systems.&lt;/p&gt;

&lt;h3&gt;
  
  
  Store Secrets with the AWS CLI
&lt;/h3&gt;

&lt;p&gt;Using the AWS CLI, we’ll first create a random password.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ aws secretsmanager get-random-password
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The response will look something like the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
   “RandomPassword”: “txRxQ6#[Muq_%oVVg,0vLrDJ;7{GG^Gy”
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s now store that password in AWS Secrets Manager. Take note of the name of the secret.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ aws secretsmanager create-secret  \
    ––name test-secret \
    ––secret-string 'txRxQ6#[Muq_%oVVg,0vLrDJ;7{GG^Gy'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On completion, you will get a response with the ARN, Name and VersionId.&lt;/p&gt;

&lt;h3&gt;
  
  
  Create the .NET Test Application
&lt;/h3&gt;

&lt;p&gt;With the secret created, let’s create a test application that integrates with AWS Secrets Manager which will allow us to retrieve the stored secret. For this example, we will use a .NET API.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ dotnet new webapi ––name Api
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that we have a reference application, let’s pull in the Nuget that contains the AWS Secrets Manager Caching library with the following command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ dotnet add Api/ package AWSSDK.SecretsManager.Caching
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s go into the Program.cs file within the new "Api" application and add a few lines directly below the builder variable declaration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;builder.Services.AddScoped&amp;lt;IAmazonSecretsManager&amp;gt;(a =&amp;gt;
      new AmazonSecretsManagerClient(RegionEndpoint.USEast1)
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These lines will setup the dependency injection so that when a class requires an IAmazonSecretsManager based class, an AmazonSecretsManagerClient will be supplied.&lt;/p&gt;

&lt;p&gt;The Program.cs file should now look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using Amazon;
using Amazon.SecretsManager;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddScoped&amp;lt;IAmazonSecretsManager&amp;gt;(a =&amp;gt;
      new AmazonSecretsManagerClient(RegionEndpoint.USEast1)
);

builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To demonstrate the use of Secrets Manager, let’s create a Controller named SecretController.cs. In the SecretController class, let's create a GetSecret method with the following logic. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;This exercise is obviously for demonstration purposes only and not based on a true use case.&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[HttpGet]
public async Task&amp;lt;IActionResult&amp;gt; GetSecret()
{
    GetSecretValueRequest request = new GetSecretValueRequest
    {
        SecretId = "test-secret",
        VersionStage = "AWSCURRENT"
    };

    GetSecretValueResponse response = await _secretsManager.GetSecretValueAsync(request);
    return Ok(new { Secret = response.SecretString });
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we instantiate the GetSecretValueRequest object assigning the SecretId for the secret that we are trying to fetch and also ask for the latest version of the secret by setting the VersionStage to AWSCURRENT. The last step is to send the request and parse the response.&lt;/p&gt;

&lt;p&gt;Let’s take a look at the complete SecretController class.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using Amazon.SecretsManager;
using Amazon.SecretsManager.Model;
using Microsoft.AspNetCore.Mvc;

namespace Api.Controllers;

[ApiController]
[Route("[controller]")]
public class SecretController : ControllerBase
{
    private readonly IAmazonSecretsManager _secretsManager;

    public SecretController(IAmazonSecretsManager secretsManager)
    {
        _secretsManager = secretsManager;
    }

    [HttpGet]
    public async Task&amp;lt;IActionResult&amp;gt; GetSecret()
    {
        GetSecretValueRequest request = new GetSecretValueRequest
        {
            SecretId = "test-secret",
            VersionStage = "AWSCURRENT"
        };

        GetSecretValueResponse response = await _secretsManager.GetSecretValueAsync(request);
        return Ok(new { Secret = response.SecretString });
    }
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Testing the Application
&lt;/h3&gt;

&lt;p&gt;First, let’s get the "Api" application up and running with the following .NET CLI command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ dotnet run ––project Api/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;*Note, here we have configured the app to run on port 5000. Your app port may very.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In your favorite browser, let’s navigate to &lt;a href="http://localhost:5000/secret" rel="noopener noreferrer"&gt;http://localhost:5000/secret&lt;/a&gt;. You should see something like the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
   "secret": "txRxQ6#[Muq_%oVVg,0vLrDJ;7{GG^Gy"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Keep the browser open for a test after we practice a couple more commands.&lt;/p&gt;

&lt;p&gt;Let’s go back to the CLI and create a new password to store.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ aws secretsmanager get-random-password
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Again, you should see something like the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
   “RandomPassword”: “0)r}|iRvK2H,%&amp;lt;R9tAJNDu&amp;lt;M@gw*OUD-”
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copy the generated password and then let’s update the secret like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ aws secretsmanager put-secret-value \
    ––secret-id test-secret \ 
    ––secret-string ‘0)r}|iRvK2H,%&amp;lt;R9tAJNDu&amp;lt;M@gw*OUD-’
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On completion, you will see a response with values for ARN, Name, VersionId, and VersionStages.&lt;/p&gt;

&lt;p&gt;Let’s return to the browser and give it a refresh. If you closed the browser, just reopen the browser and browse to: &lt;a href="http://localhost:5000/secret" rel="noopener noreferrer"&gt;http://localhost:5000/secret&lt;/a&gt;. You should now see the value you just entered for the secret and the response should look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
   "secret": "0)r}|iRvK2H,%&amp;lt;R9tAJNDu&amp;lt;M@gw*OUD-"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With our tests complete, let’s delete that secret.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ aws secretsmanager delete-secret ––secret-id test-secret
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;p&gt;That’s it! We have concluded this post where we went over reading AWS Secrets Manager secrets from within a .NET application as well as creating, updating and deleting secrets in AWS Secrets Manager via the AWS CLI.&lt;/p&gt;

</description>
      <category>serveless</category>
      <category>secretsmanager</category>
      <category>dotnet</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Use AWS Systems Manager Parameter Store as a .NET Configuration Provider</title>
      <dc:creator>Kurt Feeley </dc:creator>
      <pubDate>Tue, 17 May 2022 14:50:11 +0000</pubDate>
      <link>https://dev.to/aws-builders/use-aws-systems-manager-parameter-store-as-a-net-configuration-provider-1e68</link>
      <guid>https://dev.to/aws-builders/use-aws-systems-manager-parameter-store-as-a-net-configuration-provider-1e68</guid>
      <description>&lt;p&gt;Over the last few years, Microsoft has made many changes to improve your configuration management strategy in .NET. Long gone are the days where you have limited configuration options. In .NET, there are now out of the box options for INI,  JSON, XML, command-line arguments, in-memory stores, environment variables and key-per-file, et al. And, if those options weren’t enough, custom configuration providers can be developed. Here, we'll focus on a configuration provider built by AWS that integrates with what my colleague calls the Swiss Army Knife for AWS configuration management -- AWS Systems Manager Parameter Store. &lt;/p&gt;

&lt;p&gt;AWS Systems Manager Parameter Store provides secure, hierarchical storage for configuration data as well as secrets. With AWS Systems Manager Parameter Store, you can securely store things like passwords and secrets, but also database connection strings, UNC network paths, URLs and the like.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk1hztbtjlzq8ok3ty53h.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk1hztbtjlzq8ok3ty53h.jpg" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Photo by &lt;a href="https://unsplash.com/@pf91_photography?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Patrick&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/swiss-army-knife?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Solution
&lt;/h2&gt;

&lt;p&gt;In this tutorial, we’ll take a look at a .NET configuration provider developed by AWS that integrates with &lt;a href="https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-parameter-store.html" rel="noopener noreferrer"&gt;AWS Systems Manager Parameter Store&lt;/a&gt;. We'll develop a .NET API that we'll use to read configuration data from Parameter Store and we'll use the AWS CLI to seed that configuration data.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;p&gt;To complete this solution, you will need the .&lt;a href="https://docs.microsoft.com/en-us/dotnet/core/tools/" rel="noopener noreferrer"&gt;NET CLI&lt;/a&gt; which is included in the &lt;a href="https://dotnet.microsoft.com/download/visual-studio-sdks" rel="noopener noreferrer"&gt;.NET 6 SDK&lt;/a&gt;. In addition, you will need to download the &lt;a href="https://aws.amazon.com/cli/" rel="noopener noreferrer"&gt;AWS CLI&lt;/a&gt; and &lt;a href="https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html" rel="noopener noreferrer"&gt;configure your environment&lt;/a&gt;. You will also need to create an AWS IAM user with programmatic access with the appropriate permissions to create and read parameters in AWS Systems Manager Parameter Store.&lt;/p&gt;

&lt;p&gt;Warning: some AWS services may have fees associated with them.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Dev Environment
&lt;/h3&gt;

&lt;p&gt;This tutorial was developed using Ubuntu 20.04, AWS CLI v2, .NET 6 SDK and Visual Studio Code 1.66.2. Some commands/constructs may very across systems.&lt;/p&gt;

&lt;h3&gt;
  
  
  Create the Config Data with the AWS CLI
&lt;/h3&gt;

&lt;p&gt;First, let’s use the AWS CLI to &lt;a href="https://docs.aws.amazon.com/cli/latest/reference/ssm/put-parameter.html" rel="noopener noreferrer"&gt;create a few parameters in Parameter Store&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ aws ssm put-parameter ––name=/testapp/test-key \
     ––value=test-value ––type=String
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ aws ssm put-parameter ––name=/testapp/test-key2 \
     ––value=test-value2 ––type=String
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ aws ssm put-parameter ––name=/testapp2/test-key3 \
     ––value=test-value3 ––type=String
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;* Notice the difference between the first two parameters and the last one?&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Develop the Test App
&lt;/h3&gt;

&lt;p&gt;Now that we have some parameters in the Parameter Store, let’s create an application that will pull the key/value data as configuration. For this, we will use a simple API to illustrate the process. Use the following command to create a stubbed out .NET API:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ dotnet new webapi ––name Api
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With the API in place, we now need to pull in the AWS Nuget package that contains the configuration provider for AWS Systems Manager Parameter Store. Use the following command to add the package reference:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ dotnet add Api/ \
     package Amazon.Extensions.Configuration.SystemsManager
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The next step is to modify the Program.cs file to wire up the new configuration provider. Let’s modify Program.cs by adding the following line just below the builder variable declaration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;builder.WebHost.ConfigureAppConfiguration(
                c =&amp;gt; {

                    c.AddSystemsManager(source =&amp;gt;{
                        source.Path = "/testapp";
                        source.ReloadAfter =
                            TimeSpan.FromMinutes(10);
                    });
                }
            );
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Program.cs file should now look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureAppConfiguration(
                c =&amp;gt; {

                    c.AddSystemsManager(source =&amp;gt;{
                        source.Path = "/testapp";
                        source.ReloadAfter =
                            TimeSpan.FromMinutes(10);
                    });
                }
            );

builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So far, we have created a simple API and brought in a package that allows us to use AWS Parameter Store as a configuration store. The next step is to create a controller so that we can view the configuration data that is fetched from AWS Parameter Store. This exercise is obviously for demonstration purposes only and not based on a true use case.&lt;/p&gt;

&lt;p&gt;Let’s go into the Controllers folder and create a file named, ParametersController.cs, following the standard structure of a controller class. In this file we’ll create a method named, GetParameter and we’ll complete the method and class like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using Microsoft.AspNetCore.Mvc;

namespace Api.Controllers;

[ApiController]
[Route("[controller]")]
public class ParameterController : ControllerBase
{
    private IConfiguration _configuration;

    public ParameterController(IConfiguration configuration)
    {
        _configuration = configuration;
    }

    [HttpGet]
    public IActionResult GetParameter()
    {

        string parameter1 = _configuration["test-key"];
        string parameter2 = _configuration["test-key2"];
        string parameter3 = _configuration["test-key3"];

        return Ok(new List&amp;lt;string&amp;gt; { parameter1, parameter2, parameter3 });

    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With the controller complete, we should be ready to test our application. Let’s start the application with the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ dotnet run ––project Api/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;*Note, here we have configured the app to run on port 5000.  Your app port may very.&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;Now that the application is running, let’s navigate to, &lt;a href="http://localhost:5000/Parameter" rel="noopener noreferrer"&gt;http://localhost:5000/Parameter&lt;/a&gt; in your favorite browser. You should see a response that looks something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[
    "test-value",
    "test-value2",
    null
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that test-value3 is not present. This is because when we set up our configuration provider in Program.cs, we set the path to “/testapp”. By setting the path, Parameter Store is going to give us all parameters that are prefixed with the /testapp path. When creating the third parameter, we used a path of /testapp2, which causes the third parameter to be omitted.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;We have completed the tutorial, learning to create data in AWS Systems Manager Parameter Store via the AWS CLI as well as creating an application in AWS.NET to pull the configuration data from AWS Systems Manager Parameter Store.&lt;/p&gt;

</description>
      <category>serverless</category>
      <category>parameterstore</category>
      <category>dotnet</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Three Steps to Create a .NET AWS Lambda Function with an HTTPS Endpoint</title>
      <dc:creator>Kurt Feeley </dc:creator>
      <pubDate>Mon, 02 May 2022 16:33:43 +0000</pubDate>
      <link>https://dev.to/aws-builders/three-steps-to-create-a-net-aws-lambda-with-a-built-in-https-endpoint-2mb4</link>
      <guid>https://dev.to/aws-builders/three-steps-to-create-a-net-aws-lambda-with-a-built-in-https-endpoint-2mb4</guid>
      <description>&lt;p&gt;AWS Lambda, which has often been credited as changing the way that we think about software and how we architect software,  &lt;a href="https://aws.amazon.com/blogs/compute/aws-lambda-is-generally-available" rel="noopener noreferrer"&gt;arrived in 2015&lt;/a&gt; with much fanfare. Years later, Lambda's use continues to grow and AWS is still adding features.&lt;/p&gt;

&lt;p&gt;If there had been one complaint by software developers, engineers, architects and the like, it is the one obvious missing feature -- a URL that could be assigned directly to an AWS Lambda function. Now, let's be honest, AWS API Gateway integrates with AWS Lambda and the process of integration is pretty straightforward. But, wouldn't it be nice to check a box in the AWS console and have a URL assigned to your Lambda function? Well, the wait is over, because that's exactly &lt;a href="https://aws.amazon.com/blogs/aws/announcing-aws-lambda-function-urls-built-in-https-endpoints-for-single-function-microservices/" rel="noopener noreferrer"&gt;the feature that AWS recently released for Lambda&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fszcpkxji4j833nrnvygf.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fszcpkxji4j833nrnvygf.jpg" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Photo by &lt;a href="https://unsplash.com/@bonniekdesign?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Bonnie Kittle&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/lamb?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Solution
&lt;/h2&gt;

&lt;p&gt;In this tutorial, we will build a simple .NET Lambda function that will be invoked from a URL.  When invoked, the Lambda function will read any query string parameters in the URL and return a JSON array of the query string parameter values. In addition, we will create the AWS Lambda function, the Lambda function URL, the Lambda function execution role, and the supporting policies using the the AWS CLI.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;p&gt;To complete this tutorial, you will need the &lt;a href="https://docs.microsoft.com/en-us/dotnet/core/tools/" rel="noopener noreferrer"&gt;.NET CLI&lt;/a&gt; which is included in the &lt;a href="https://dotnet.microsoft.com/download/visual-studio-sdks" rel="noopener noreferrer"&gt;.NET 6 SDK&lt;/a&gt;. In addition, you will need to download the &lt;a href="https://aws.amazon.com/cli/" rel="noopener noreferrer"&gt;AWS CLI&lt;/a&gt; and &lt;a href="https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html" rel="noopener noreferrer"&gt;configure your environment&lt;/a&gt;. You will also need to create an IAM user with programmatic access to &lt;a href="https://aws.amazon.com/lambda/" rel="noopener noreferrer"&gt;AWS Lambda&lt;/a&gt; and &lt;a href="https://aws.amazon.com/iam" rel="noopener noreferrer"&gt;IAM&lt;/a&gt; with the appropriate permissions to create and modify Lambda functions, create Lambda function URLs, create IAM roles and IAM policies. &lt;/p&gt;

&lt;p&gt;Warning: some AWS services may have fees associated with them.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This tutorial was developed using Ubuntu 20.04, AWS CLI v2, .NET 6 SDK and Visual Studio Code 1.66.2. Some commands/constructs may very across systems.&lt;/em&gt;&lt;/p&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;br&gt;"To create a function, you need a &lt;strong&gt;&lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/gettingstarted-package.html" rel="noopener noreferrer"&gt;deployment package&lt;/a&gt;&lt;/strong&gt; and an &lt;strong&gt;&lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/intro-permission-model.html#lambda-intro-execution-role" rel="noopener noreferrer"&gt;execution role&lt;/a&gt;&lt;/strong&gt;." — &lt;a href="https://docs.aws.amazon.com/cli/latest/reference/lambda/create-function.html" rel="noopener noreferrer"&gt;docs.aws.amazon.com&lt;/a&gt;&lt;br&gt;
&lt;br&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  1) Creating a Lambda Deployment Package
&lt;/h2&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h3&gt;
  
  
  Developing a .NET AWS Lambda Function
&lt;/h3&gt;

&lt;p&gt;To keep our Lambda function lean, we will start with a .NET class library.  We can create the .NET class library with the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ dotnet new classlib -n LambdaWithUrl
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With the .NET class library created, let's change the directory to the newly created project folder, LambdaWithUrl and add the package dependencies like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ dotnet add package Amazon.Lambda.APIGatewayEvents
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ dotnet add package Amazon.Lambda.Serialization.Json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ dotnet add package Amazon.Lambda.Core
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ dotnet add package AWSSDK.Lambda
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ok, now that we have the bones of the Lambda function in place, let’s get into the code. For this tutorial, the code will be very concise.&lt;/p&gt;

&lt;p&gt;We are going to create one class named, “Handler”, that has one method named, “Handle”. When the Lambda function is invoked, the Handle method will be called and it will process the data that is passed in from AWS Lambda. Since we are going to be invoking this Lambda via a URL, the method parameter type of the Handle method will be APIGatewayProxyRequest. To get an idea of the data that can be processed by the Lambda function, checkout an &lt;a href="https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-lambda.html#http-api-develop-integrations-lambda.proxy-format" rel="noopener noreferrer"&gt;example JSON Payload&lt;/a&gt; or the &lt;a href="https://github.com/aws/aws-lambda-dotnet/blob/master/Libraries/src/Amazon.Lambda.APIGatewayEvents/APIGatewayProxyRequest.cs" rel="noopener noreferrer"&gt;C# APIGatewayProxyRequest class&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The Lambda function processing logic is simple in this tutorial. Essentially, when this Lambda function is invoked, the query string values will be plucked out and returned. Consumers of this Lambda function’s URL will receive a JSON array of strings containing the values from the query string parameters that were used to invoke the function.&lt;/p&gt;

&lt;p&gt;Here’s the Handler class in its entirety.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using Amazon.Lambda.Core;
using Amazon.Lambda.APIGatewayEvents;
using Amazon.Lambda.Serialization.Json;

namespace LambdaWithUrl;

public class Handler
{
    [LambdaSerializer(typeof(JsonSerializer))]
    public IEnumerable&amp;lt;String&amp;gt; Handle(APIGatewayProxyRequest apiGatewayProxyRequest)
    {
        return apiGatewayProxyRequest?.QueryStringParameters?.Values ?? new String[0];
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it for the coding of our simple .NET AWS Lambda function.  &lt;/p&gt;

&lt;h3&gt;
  
  
  Packaging the .NET AWS Lambda Function
&lt;/h3&gt;

&lt;p&gt;For this tutorial, we will create a zip file deployment package of our .NET Lambda function.&lt;/p&gt;

&lt;p&gt;The first step is to publish the .NET application using the following .NET CLI command. Notice the MSBuild GenerateRuntimeConfigurationFiles parameter. Setting GenerateRuntimeConfigurationFiles to true will instruct the .NET CLI to generate the (appname).runtimeconfig.json &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/csharp-package.html" rel="noopener noreferrer"&gt;file that AWS Lambda requires&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ dotnet publish \
   -c Release \
   -o lambda \
   /p:GenerateRuntimeConfigurationFiles=true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s change the directory to the “lambda” directory and zip all the directory’s contents with the following command. There are many options to zip files across Windows, Linux and macOS.  Here you will see the command that was used in the Ubuntu environment.  Whichever option you choose, make sure you zip the contents of the folder and not to include the folder in the zip file. Also notice that the lambda.zip file is placed in the LambdaWithUrl directory, which is important for a forthcoming step.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ zip ../lambda.zip *
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s it, our AWS Lambda function is packaged and ready to be uploaded.&lt;/p&gt;





&lt;h2&gt;
  
  
  2) Set Permissions
&lt;/h2&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h3&gt;
  
  
  Create the Lambda Function Execution Role
&lt;/h3&gt;

&lt;p&gt;With the deployment package set to go, we can turn our attention to the execution role.&lt;/p&gt;

&lt;p&gt;The execution role has two policies. The trust policy defines what principal can use or assume the role. The second policy defines the AWS services and resources in which the role has access to.&lt;/p&gt;

&lt;p&gt;Let’s change the directory back to the project directory (LambdaWithUrl) and create a file named trust-policy.json with the following content.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "lambda.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s use the following command to create the execution role, using the trust-policy.json file to create the trust policy.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ aws iam create-role \
   --role-name lambda-with-url-execution-role \
   --assume-role-policy-document file://trust-policy.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With the role created, let’s define the permissions for the Lambda function. You could create your own policy and attach it, but for this tutorial we’ll attach the AWS AWSLambdaBasicExecutionRole managed policy. The AWSLambdaBasicExecutionRole simply will grant the Lambda function permission to create logs in &lt;a href="https://aws.amazon.com/cloudwatch/" rel="noopener noreferrer"&gt;Amazon CloudWatch&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let’s use the following command to attach the AWSLambdaBasicExecutionRole policy.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ aws iam attach-role-policy \
   --role-name lambda-with-url-execution-role \
   --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And, with that, the Lambda function execution role is complete.&lt;/p&gt;

&lt;h2&gt;
  
  
  3) Configure the Lambda Function with the CLI
&lt;/h2&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h3&gt;
  
  
  Create the .NET Lambda Function
&lt;/h3&gt;

&lt;p&gt;With the Lambda function execution role completed and the deployment package ready to be uploaded, let’s create the Lambda function using the AWS CLI with the command below, replacing aws-account-number with your AWS account number.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ aws lambda create-function  \
   --function-name lambda-with-url  \
   --runtime dotnet6  \
   --handler LambdaWithUrl::LambdaWithUrl.Handler::Handle  \
   --description lambda-function-with-url  \
   --zip-file fileb://lambda.zip  \
   --role arn:aws:iam::(aws-account-number):role/lambda-with-url-execution-role
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When completed, you should get a response with a JSON object with elements of FunctionName, FunctionArn, Runtime, etc.&lt;/p&gt;

&lt;h3&gt;
  
  
  Create the Lambda Function URL
&lt;/h3&gt;

&lt;p&gt;The last step is to create a URL for the Lambda function. This can be done in two parts. Note: for this tutorial we allow public access and set function-url-auth-type to NONE. &lt;strong&gt;Scrutinize your security needs and set the URL permissions accordingly&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;First, we need to create the Lambda URL and we can do so with this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ aws lambda create-function-url-config  \
   --function-name lambda-with-url  \
   --auth-type NONE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When completed, you should get a response with a JSON object with elements of FunctionUrl, FunctionArn, AuthType, etc.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Record the FunctionUrl for testing.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Finally, we need to set permissions in order to access the URL.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ aws lambda add-permission  \
   --function-name lambda-with-url  \
   --statement-id FunctionURLAllowPublicAccess  \
   --action lambda:InvokeFunctionUrl  \
   --principal "*"  \
   --function-url-auth-type NONE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When completed, you should get a response with a JSON object with the element of Statement.&lt;/p&gt;

&lt;p&gt;OK, the Lambda function has been created along with the associated URL. The next step is to give the .NET Lambda function a test using its URL.&lt;/p&gt;

&lt;h3&gt;
  
  
  Testing the .NET AWS Lambda Function
&lt;/h3&gt;

&lt;p&gt;Open a browser and browse to the Lambda URL that you recorded earlier. You should see an empty JSON array — [ ]. Append the following to the end of the URL and hit enter:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;?param1=value1&amp;amp;param2=value2&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Once the page loads, you should see the following response.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[
   "value1",
   "value2"
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;We have concluded this tutorial where you have learned how to build a .NET Lambda function with an associated URL. You also learned how to create an IAM role and attach an IAM policy using the AWS CLI.&lt;/p&gt;

&lt;p&gt;*** Don't forget to remove any unwanted AWS resources that were created for this tutorial ***&lt;/p&gt;

</description>
      <category>serverless</category>
      <category>lambda</category>
      <category>dotnet</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
