Friday, September 13, 2024

F# as a scripting language

 


If you read on F# Interactive (dotnet) Reference - .NET | Microsoft Learn, F# language has an official interactive/interpreter support from Microsoft unlike C#. Let me know if I'm wrong guys please comment.

This means you could use F# in places where you are using interpreted/scripting language like Python, Perl, Ruby

Advantage you get to consume libraries from .NET ecosystem and strong type system of F#


At this time of writing, I'm using dotnet sdk 8.0


Step 1: Install paket

dotnet tool install -g paket
paket init

Edit "paket.dependencies" and add your libraries you need.
For this example, I want to add "FSharp.Core" version "8.0.300" and  "UUIDNext" version "3.0.0"

sources https://api.nuget.org/v3/index.json
storage: none

nuget FSharp.Core 8.0.300


Step 2: Use "paket install" to install dependencies then "paket generate load-scripts --framework net8.0" to generate script to use to reference your dependencies in the script you will create

paket install
paket generate load-scripts --framework net8.0

From one of the answers in stackoverflow, With the most recent cross plaform net installed and the most recent linux (coreutil 8.30<=) and bsd / mac os releases. You can use the following shebang for F# .fsx scripts.

#!/usr/bin/env -S dotnet fsi


Here is a sample F# fsx script  I will create named "uuid.fsx"

#!/usr/bin/env -S dotnet fsi
#load @".paket/load/net8.0/main.group.fsx"


open System
open UUIDNext

let sequentialUuid = Uuid.NewDatabaseFriendly(Database.SQLite)
Console.WriteLine($"This is a database friendly UUID : {sequentialUuid}")
We can run this script from bash like we do with other scripts
./uuid.fsx

or directly using dotnet command

dotnet fsi uuid.fsx

Output:

This is a database friendly UUID : 0191ea67-c7bf-77e6-af05-483dea4b1c62
Nice!. we are done


Friday, September 6, 2024

Terraform: How to migrate from old to new state file

 

When you are in production. One of the things you are gonna ask to yourself is how to avoid updating too soon the existing state file in which you might make mistake.

You could create backups but then again, we want to have an extra step to prevent doing restoring the existing state file due to wrong migration.


One use case will be one of our cloud resources will be manage by another team with their own terraform repository


Scenario:

Terraform state A (existing): has the following resource that you want to migrate to Terraform state B (new).

* aws_iam_role_policy_attachment.service_a


Step 1: Pull state file from each terraform repo


Terraform state A (existing):

cd {{ repo-a }}
terraform state pull > $HOME/backup.tfstate
cp $HOME/backup.tfstate $HOME/current.tfstate


Terraform state B (new):

cd {{ repo-b }}
terraform state pull > $HOME/destination.tfstate


Step 2: Migrate resource to new terraform state file


terraform state mv -state=$HOME/current.tfstate -state-out=$HOME/destination.tfstate aws_iam_role_policy_attachment.service_a aws_iam_role_policy_attachment.service_a 

Step 3: Push new state file 

cd {{ repo-b }}
terraform state push $HOME/destination.tfstate


You still have your backup and resource is already migrated and your original terraform repo is still untouched nice!!


Step 4: Validate new terraform repo. Just do a terraform plan. review if output meets your expectation otherwise you need to revisit your step if you did something wrong.

cd {{ repo-b }}
terraform plan

Step 5: Remove resource from old repo
cd {{ repo-a }}
terraform state rm aws_iam_role_policy_attachment.service_a 


Congrats, your done

F# as a scripting language

  If you read on  F# Interactive (dotnet) Reference - .NET | Microsoft Learn , F# language has an official interactive/interpreter support f...