Author Archives: purpleblob

Mix and project dependencies in Elixir

Like many other languages, there’s a lot of third party packages and shared code for the Elixir language.

If we use mix to create a new project you’ll get a mix.exs script file generated. Let’s take a look at one created for one of my projects

defmodule TestLang.MixProject do
  use Mix.Project

  def project do
    [
      app: :test_lang,
      version: "0.1.0",
      elixir: "~> 1.17",
      start_permanent: Mix.env() == :prod,
      deps: deps()
    ]
  end

  # Run "mix help compile.app" to learn about applications.
  def application do
    [
      extra_applications: [:logger]
    ]
  end

  # Run "mix help deps" to learn about dependencies.
  defp deps do
    [
      # {:dep_from_hexpm, "~> 0.3.0"},
      # {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"}
    ]
  end
end

The project section is where we set the application name, version etc. The deps section is where we add dependencies that we want to pull into our project.

We can pull in code from git or from https://hex.pm/.

Let’s start by adding a dependency on a package from hex.pm, I’m going to add the UUID package https://hex.pm/packages/uuid, so amend the deps section to look like this

defp deps do
  [
    {:uuid, "~> 1.1"}
  ]
end

The code was copied from the packages hex.pm page where it has code for various configurations.

We can check the state of our dependencies by typing mix deps. In my case it tells me the dependency is not available, I need to run mix deps.get.

We don’t need to compiler the dependency as it’ll automatically compile when we need it, but you can compile it using mix deps.compile if you prefer.

When you bring dependencies into your project you’ll see a deps folder created and similar to node_modules in web/node development, you’ll see the dependency code in this folder.

Let’s try UUID out (as per it’s documentation https://hexdocs.pm/uuid/readme.html), I created a lib/try_uuid.ex file and added the following code

defmodule TryUuid do

  def create() do
    UUID.uuid1()
  end
end

Run up iex using iex -S mix to allow access to the project and it’s dependencies. Finally run the code TryUuid.create() and if all went well you’ll get a UUI created.

Let’s add a dependency from GitHub, back to the mix.exs and change the deps section to like this

defp deps do
  [
    {:uuid, "~> 1.1"},
    {:better_weighted_random, git: "https://github.com/JohnJocoo/weighted_random.git" }
  ]
end

I basically picked the package from GitHub by searching for packages and looking for something fairly simple to try – this one seemed as good as any. There were no tags so I’ve not included a version with the dependency.

Now go through the process of mix get.deps now add a file, mine’s try_random.ex with the following code

defmodule TryRandom do
  def create() do
    WeightedRandom.take_one([{:'1', 0.5}, {:'2', 1.0}, {:'3', 2.0}])
  end
end

Compile using mix compile and then run up iex -S mix and finally execute the command TryRandom.create() and if all went well you’ll get some randomly selected value from the list give within the code.

AWS CloudFormation

Disclaimer: This post sat in draft for a while as I’m not using AWS at the moment I cannot guarantee that all works still or the post is 100% complete, but I’m going to publish it anyway, in case it’s of use.

AWS CloudFormation is a service that is essentially a way to group together AWS resources into a stack. We can define the stack using the AWS Dashboard or using either JSON or YAML.

For example, in JSON

{
  "Resources": {
    "S3Bucket": {
      "Type": "AWS::S3::Bucket",
      "Properties": {
        "BucketName": "mybucket"
      }
    }
  }
}

or in YAML

Resources:
  S3Bucket:
    Type: 'AWS::S3::Bucket'
    Properties:
      BucketName: mybucket

In this example the S3 bucket will be created within the Stack. Remember the bucket name must be unique across all accounts.

  • From the dashboard type CloudFormation into the search box
  • Once you’re on the CloudFormation page click the Create stack button

From the Create stack page you can select a JSON or YAML template from your local machine, an Amazon S3 URL or from a Git repos. using the Template is ready option. Or you can Use a sample template to load a pre-existing stack, for example LAMP, Ruby on Rails, WordPress etc. Or you can select the Create template in designer option to use the stack designer.

Let’s see what we can do with CloudFormation by creating our simple Echo service web API and let some tools generate our CloudFormation configuration file for us.

Setting up our credentials

First we’re going to need to set up our credentials.

You’ll hopefully have stored the credentials when you create your IAM user, access id and secret are what’s required for this next step.

If you prefer to handle this from a UI such as Visual Studio Extensions, then you can use the edit credential button in the AWS Explorer (load via the menu View | AWS Explorer) but let’s first do this ourselves.

Credentials are obviously meant to be kept secret, so they’re stored on your local machine in the folder C:\Users\<your-username>\.aws in the file named credentials. The file is an INI type file and should look like this when you’ve added your credentials

[profilename]
aws_access_key_id = IDSUPPLIEDBYAWS
aws_secret_access_key = SECRETSUPPLIEDBYAWS

The profilename is the profile name as seen in tools such as AWS Explorer or will be used in the CLI, this allows us to have multiple access key/secrets for multiple apps.

Note: if you edit this file via AWS Explorer it will add further information to the profile

Using Visual Studio Extensions

If you install the AWS extensions for Visual Studio, you can create CloudFormation based applications using the project templates. If you create yourself a project based upon AWS Serverless Application (.NET Core – C#) for example, you’ll then get the option to choose a project type, I chose Minimal Wweb API.

The resultant project includes everything you need to build and deploy your application to AWS serverless.

For example from Visual Studio 2022 with the current AWS Extensions installed

  • Create a new project, select AWS Serverless Application (.NET Core – C#) or the with Tests version
  • Once create simply replace the minimal API root method with the following
    app.MapGet("/", () => "Use /echo?text=<text>");
    app.MapGet("/echo", (string text) => $"Echo: {text}");
    
  • Open the serverless.template file and change the Descriptiom to something meaningful to your project
  • Build and run locally to check everything works, i.e. /echo?text=Scooby should echo back Scooby
  • We can now simply right mouse click on the serverless.template file and select Publish to AWS Lambda
  • From the Publish to AWS Lambda popup, enter a Stack Name if it doesn’t exist it will be created
  • Enter an S3 Bucket name or click the New button and supply a name
  • You might need to change the AWS Credentials if required for your specific application and Region
  • Click Publish and if all goes well, your application will be published to a stack in AWS and upon completion the AWS extension will show the URL for you service and you can go and try it

At this point if you log into AWS using the same IAM account that your stack was deployed to, go to CloudFormation and you’ll see our stack was added, it should show Status as CREATE_COMPLETE it’ll have the desription we changed in the serverless.template file. In the Outputs tab we can see the ApiURL (in case you forgot to note it down).

Now if you enter S3 into the search box and go and look at our buckets, you’ll see the bucket we created and finally if you enter Lambda into the search box and go to the Lambda Functions page you’ll see the function name for our Web API.

I’m not going to dig too much into the serverless.template file but note that the Type

"Type": "AWS::Serverless::Function",

Essentially creates the web API as a lamba function, sets up the IAM execution role and adds the HTTP triggers to invoke the function.

Valid types are as followis

  • AWS::Serverless::Function as already looked at this will create the Lambda function, the execution role and any required triggers
  • AWS::Serverless::Api denotes a resource type for creating an API Gateway
  • AWS::Serverless::HttpApi denotes a resource type used to create REST API’s
  • AWS::Serverless::SimpleTable denotes a resource type to create a DynamoDB table with a single primary key

error NU1301: Unable to load the service index for source https://api.nuget.org/v3/index.json

I was running a docker build against a .NET Web API project, on a Windows OS machine connected to a VPN and I was getting the error error NU1301: Unable to load the service index for source https://api.nuget.org/v3/index.json.

This fixed it for me…

  • Open Docker Desktop
  • Click the Settings button
  • Click on the Docker Engine option
  • Add a dns section to the JSON configuration, i.e.
    {
      "dns": [
          "8.8.8.8"
      ],
      "experimental": false
    }
    

Azure web app with IIS running ASP.NET core/Kestrel

When you deploy your ASP.NET core (.NET 8) to an Azure web app, you’ll have likely created the app to work with Kestrel (so you can deploy to pretty much any environment). But when you deploy as an Azure Web App, you’re essentially deploying to an IIS application.

So we need for IIS to simply proxy across to our Kestrel app. We achieve this by adding a Web.config to the root of our published app. and we’ll have configuration such as below

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <location path="." inheritInChildApplications="false">
    <system.webServer>
      <handlers>
        <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
      </handlers>
      <aspNetCore processPath=".\MyAspNetCoreApp.exe" stdoutLogEnabled="false" stdoutLogFile="\\?\%home%\LogFiles\stdout" hostingModel="inprocess" />
    </system.webServer>
  </location>
</configuration>

Nesting files in Visual Studio

It’s, sometimes, useful to nest files within our solution within Visual Studio 2022 – we see this automatically with appsettings.json or .designer.cs files etc.

We can however make Visual Studio nest any files, so for example, create a file named .filenesting.json within your project’s folder, here’s an example which nests some .generated.cs files which I am using as my custom auto-generated code

{
  "help": "https://go.microsoft.com/fwlink/?linkid=866610",
  "root": true,

  "dependentFileProviders": {
    "add": {
      "extensionToExtension": {
        "add": {
          ".generated.cs": [
            ".cs"
          ]
        }
      }
    }
  }
}

Note: you will need to unload and reload your project to get Visual Studio to use the filenesting.

In this example if you have a MyLib.cs file a MyLib.generated.cs file the generated one will shows as a child/nested folder of the non-generated file.

You can actually use Visual Studio itself to create these files by

  • Within the solution explorer of VS 2022
  • Click the drop down arrow on the File Nesting button (which looks like a folder nested tree)
  • Click Add Custom Settings/li>
  • Supply a name for your file settings
  • If you select the Default template it will generate a file with lots of nestings that you can add to

By default using Visual Studio will create your files with the Users AppData folders.

Basic use of the Elixir interactive shell

If you’re wanting to play around with Elixir in a REPL you can use iex.

Note: To exit iex just CTRL+C twice.

Within the shell we can simply type in code on a line and press enter to evaluate it. So for example type

le = [1,10,20]

press enter and the shell will display the list now bound to the value l.

Now type

length(l)

and the shell should display 3, the length of the list.

To get help from the shell, execute

h()

Compiling a module into iex

Whilst you’re developing your modules you might which to test them via the shell, in which case from you can load it when you start iex using (in this case my module in called math.ex)

iex math.ex

or if you’ve already started iex, simple use

c "math.ex"

The line above compiles your code and loads into iex so it’s now available to call from the shell.

If you want to view the exports on a module (in this example on my Math module), use the command

exports(Math)

Running PowerShell in a Windows container

I was messing around with Windows based docker images, running IIS and an ASP.NET 4.7.x application and wanted to connect to it’s “shell” to explore what was installed etc.

For Linux container you’ll probably use bash. From a Windows container we can just use powershell

Just change “the-container-id” to the id of the container you wish to connect to

docker container exec -it the-container-id powershell

What’s the purpose of the lang attribute in HTML ?

When creating an an HTML document, we would include the lang attribute to specify the language of the content within the document.

This allows browsers, screen readers etc. to correctly interpret and present content and allows screen readers to pronounce words in the style of the language selected. So for example we’d have

<!DOCTYPE html>
<html lang="en">
  <!-- content -->
</html>

Note that we use the short form language, i.e. “en” or long form such as “en-GB” or “en-US”

Obviously this would need to be changed if your application support i18n, so we might use something like the following, if we’re using something like the i18n package for React

document.documentElement.lang = i18n.language;

// OR

document.documentElement.lang = i18n.resolvedLanguage;

If you do not set the lang or set it to an empty string this simply means the language is unknown.

Whilst this post talks about the html tag, you can actually set the lang on other elements, such as paragraphs p so on a per element basis.

Creating a static web site on Azure (includes Blazor WebAssembly sites)

Azure offer a free static web site option, the process for creating a static web site is the same as creating one for a Blazor standalone application…

  • Create a resource group and/or select an existing one
  • Click Create button
  • Select or search for Static Web App via the marketplace
  • Click Create
  • I’m using the free hosting plan – so click Free, For hobby or personal projects plan type
  • I want the code to be deployed automatically from github, so ensure GitHub deployment details is set up
  • If you need to amend the GitHub account, do so
  • Set your organization, repository and branch to the github account/repo etc.
  • In Deployment configuration I use Deployment Token
  • In Advance, set your region

As part of this process, if you tie to application to your GitHub repo. you’ll also find a GitHub action’s CI/CD pipeline added to your repository which will carry out continuous deployment upon commits/merges to your main branch.

It’s likely you’ll want to map your Azure website name to DNS, I have my domain created with a different company so need to change DNS records

In Azure in the static web app, select Settings | Custom domains and Add Custom domain on other DNS (if host is not in Azure)

  • Type the url name, i.e. www.mywebsite.co.uk or my subdomain is using app.mywebsite.co.uk
  • Azure will create the e CNAME record (which I’ll show below)
  • Click Next then Add (having copied your CNAME values

In my third party host I enter DNS record

  • CNAME
  • app (or www in most cases)
  • your Azure website name (I have to have the url terminated with a .)

Is my ASP.NET core application running in Kubernetes (or Docker) ?

I came across a situation where I needed to change some logic in my ASP.NET core application dependant upon whether I was running inside Kubernetes or an Azure Web app, luckily there is an environment variable that we can use (and whilst we’re at it, there’s one for Docker as well)

var isHostedInKubernetes = 
   Environment.GetEnvironmentVariable("KUBERNETES_SERVICE_HOST") != null;
var isHostedInDocker = 
   Environment.GetEnvironmentVariable("DOTNET_RUNNING_IN_CONTAINER") == "true";