<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Sibeesh Passion</title>
	<atom:link href="https://sibeeshpassion.com/feed/" rel="self" type="application/rss+xml" />
	<link>https://sibeeshpassion.com</link>
	<description>My passion towards life</description>
	<lastBuildDate>Wed, 25 Jun 2025 18:07:04 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>/wp-content/uploads/2017/04/Sibeesh_Passion_Logo_Small.png</url>
	<title>Sibeesh Passion</title>
	<link>https://sibeeshpassion.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>React Native Android Release with Azure DevOps and Google Play Store</title>
		<link>https://sibeeshpassion.com/react-native-android-release-with-azure-devops-and-google-play-store-2/</link>
					<comments>https://sibeeshpassion.com/react-native-android-release-with-azure-devops-and-google-play-store-2/#disqus_thread</comments>
		
		<dc:creator><![CDATA[SibeeshVenu]]></dc:creator>
		<pubDate>Wed, 25 Jun 2025 18:06:57 +0000</pubDate>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[azure devops]]></category>
		<category><![CDATA[React]]></category>
		<category><![CDATA[react native android azure devops pipeline yaml]]></category>
		<category><![CDATA[react native android custom app version pipeline]]></category>
		<category><![CDATA[react native android google play store release]]></category>
		<category><![CDATA[react native android release]]></category>
		<category><![CDATA[react native android signing]]></category>
		<category><![CDATA[react native azure devops]]></category>
		<guid isPermaLink="false">https://sibeeshpassion.com/?p=14718</guid>

					<description><![CDATA[In this post, we will see how we can release a React native Android application to Google play store with custom app signing, custom app version configured from Azure DevOps pipeline build number]]></description>
										<content:encoded><![CDATA[
<h1 class="wp-block-heading">Introduction</h1>



<p>We can use React native, an open source mobile application framework by Facebook, to develop application for Android, IOS, UWP, and Web. In this post, we will see how we can release a React native Android application to Google play store with custom app signing, custom app version configured from Azure DevOps pipeline build number. Sounds interesting, right?</p>



<h1 class="wp-block-heading">Prerequisites </h1>



<ol class="wp-block-list">
<li>Make sure you have a React native application. You can follow <a href="https://learn.microsoft.com/en-us/windows/dev-environment/javascript/react-native-for-android">this doc</a> to create a dummy application.</li>



<li><a href="https://azure.microsoft.com/en-us/products/devops">Azure DevOps</a> </li>
</ol>



<h1 class="wp-block-heading">Create a dummy android pipeline</h1>



<p>Go to Pipelines in Azure DevOps and click on New pipeline, select Azure Devops, select your repository. In the Configure your pipeline section, select Android. </p>



<figure class="wp-block-image size-large"><a href="/wp-content/uploads/2025/06/image-1.png"><img fetchpriority="high" decoding="async" width="1024" height="320" src="/wp-content/uploads/2025/06/image-1-1024x320.png" alt="" class="wp-image-14727" srcset="/wp-content/uploads/2025/06/image-1-1024x320.png 1024w, /wp-content/uploads/2025/06/image-1-300x94.png 300w, /wp-content/uploads/2025/06/image-1-768x240.png 768w, /wp-content/uploads/2025/06/image-1-1536x480.png 1536w, /wp-content/uploads/2025/06/image-1-2048x641.png 2048w, /wp-content/uploads/2025/06/image-1-400x125.png 400w, /wp-content/uploads/2025/06/image-1-1918x600.png 1918w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></figure>



<p>Rename your YAML file and click save. You don&#8217;t have to run your pipeline yet.</p>



<h1 class="wp-block-heading">Application Configuration</h1>



<p>Before we create the pipeline, let&#8217;s do some configuration in our application. </p>



<h2 class="wp-block-heading">Update the Gradle file</h2>



<p>A gradle file helps us to,</p>



<ul class="wp-block-list">
<li>Add libraries and dependencies</li>



<li>Define how to build different environments (debug vs. release)</li>



<li>Sign Android APKs/AABs</li>



<li>Automate tasks (e.g., tests, publishing, versioning)</li>
</ul>



<h3 class="wp-block-heading">Configure the app versioning</h3>



<p>By default, the app gets the verson that is mentioned in the <strong>app.json</strong> file in the root folder. Just like all the other deployments, it is a great idea to have our app version name and app version code configured to the build number and build id from the pipeline. To do that let&#8217;s do the changes below in the <strong>android\build.gradle</strong> file. Remember there is also another build.gradle file in android/app folder. Under the buildscript section, add the below methods. </p>



<pre class="wp-block-code"><code>def getMyVersionCode = { -&gt;
        def code = project.hasProperty('versionCode') ? versionCode.toInteger() : -1
        println "VersionCode is set to $code"
        return code
    }

    def getMyVersionName = { -&gt;
        def name = project.hasProperty('versionName') ? versionName : "1.0"
        println "VersionName is set to $name"
        return name
    }</code></pre>



<p>Update the ext section as below.</p>



<pre class="wp-block-code"><code>ext {
        buildToolsVersion = "35.0.0"
        minSdkVersion = 24
        compileSdkVersion = 35
        targetSdkVersion = 34
        ndkVersion = "26.1.10909125"
        kotlinVersion = "1.9.24"
        versionName = getMyVersionName()
        versionCode = getMyVersionCode()
    }</code></pre>



<p>Below is the full <strong>android/build.gradle</strong> file content.</p>



<pre class="wp-block-code"><code>buildscript {
    def getMyVersionCode = { -&gt;
        def code = project.hasProperty('versionCode') ? versionCode.toInteger() : -1
        println "VersionCode is set to $code"
        return code
    }

    def getMyVersionName = { -&gt;
        def name = project.hasProperty('versionName') ? versionName : "1.0"
        println "VersionName is set to $name"
        return name
    }
    ext {
        buildToolsVersion = "35.0.0"
        minSdkVersion = 24
        compileSdkVersion = 35
        targetSdkVersion = 34
        ndkVersion = "26.1.10909125"
        kotlinVersion = "1.9.24"
        versionName = getMyVersionName()
        versionCode = getMyVersionCode()
    }
    repositories {
        google()
        mavenCentral()
    }
    dependencies {
        classpath("com.android.tools.build:gradle")
        classpath("com.facebook.react:react-native-gradle-plugin")
        classpath("org.jetbrains.kotlin:kotlin-gradle-plugin")
    }
}

apply plugin: "com.facebook.react.rootproject"</code></pre>



<p>Now go to the <strong>android\app\build.gradle</strong> file and use the new configs there. Under the android section, go to the defaultConfig and add the content below.</p>



<pre class="wp-block-code"><code>versionCode rootProject.ext.versionCode
versionName rootProject.ext.versionName</code></pre>



<p>Your final defaultConfig would looks like below.</p>



<pre class="wp-block-code"><code>defaultConfig {
        applicationId "com.yourapplicationid"
        minSdkVersion rootProject.ext.minSdkVersion
        targetSdkVersion rootProject.ext.targetSdkVersion
        versionCode rootProject.ext.versionCode
        versionName rootProject.ext.versionName

        manifestPlaceholders = &#91;
            appAuthRedirectScheme: "com.yourapplicationid"
        ]
    }</code></pre>



<h3 class="wp-block-heading">Create and upload keystore to the Secure files</h3>



<p>By default the app uses debug configuration to sign, you can see this setting <strong>signingConfigs.debug</strong> in the section buildTypes for release. You can also see that in the both cases it uses the same <strong>debug.keystore</strong> file to sign, which is not recommended for the production releases. Let&#8217;s create a new keystore file for our releases first. Run the command below. To run the keytool command, make sure to insall the <a href="https://www.oracle.com/java/technologies/downloads/?er=221886">Java development kit (JDK)</a>. Also make sure to reference the appropriate JDK version in the command.</p>



<pre class="wp-block-code"><code>C:\"Program Files"\Java\jdk-24\bin\keytool -genkeypair -v -keystore yourkey-key.keystore -alias your-alias -keyalg RSA -keysize 2048 -validity 200000</code></pre>



<p>Make sure to give <strong>large number as validity</strong> in the command as stated <a href="https://developer.android.com/studio/publish/app-signing">in this post</a>. </p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><strong>Validity (years):</strong> Set the length of time in years that your key will be valid. Your key should be valid for at least 25 years, so you can sign app updates with the same key through the lifespan of your app.</p>
</blockquote>



<p> As we have created the keystore file, let&#8217;s save them in a secured place, and good news is that the <a href="https://learn.microsoft.com/en-us/azure/devops/pipelines/library/secure-files?view=azure-devops">Azure DevOps already has a place for this</a>. </p>



<p>From Azure DevOps, go the Library under Pipelines, and click on the +Secure file option under under Secure files. </p>



<figure class="wp-block-image size-large"><a href="/wp-content/uploads/2025/06/image.png"><img decoding="async" width="1024" height="387" src="/wp-content/uploads/2025/06/image-1024x387.png" alt="" class="wp-image-14725" srcset="/wp-content/uploads/2025/06/image-1024x387.png 1024w, /wp-content/uploads/2025/06/image-300x113.png 300w, /wp-content/uploads/2025/06/image-768x290.png 768w, /wp-content/uploads/2025/06/image-1536x580.png 1536w, /wp-content/uploads/2025/06/image-2048x774.png 2048w, /wp-content/uploads/2025/06/image-400x151.png 400w, /wp-content/uploads/2025/06/image-1589x600.png 1589w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></figure>



<p>After the secure file is uploaded, it is important to allow permission for our pipeline to use it. Go to the secure file, and click on the Pipeline permissions and then click on the Add pipeline plus icon and select your pipeline. </p>



<figure class="wp-block-image size-large"><a href="/wp-content/uploads/2025/06/image-3.png"><img decoding="async" width="1024" height="373" src="/wp-content/uploads/2025/06/image-3-1024x373.png" alt="" class="wp-image-14729" srcset="/wp-content/uploads/2025/06/image-3-1024x373.png 1024w, /wp-content/uploads/2025/06/image-3-300x109.png 300w, /wp-content/uploads/2025/06/image-3-768x280.png 768w, /wp-content/uploads/2025/06/image-3-1536x560.png 1536w, /wp-content/uploads/2025/06/image-3-2048x746.png 2048w, /wp-content/uploads/2025/06/image-3-400x146.png 400w, /wp-content/uploads/2025/06/image-3-1647x600.png 1647w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></figure>



<h3 class="wp-block-heading">Configure the keystore password as pipeline variables</h3>



<p>Now it is time to create a variable group in Azure DevOps and add the secured variables. Here keyAlias and keystorePassword is the details you had provided when you were creating the keystore. </p>



<figure class="wp-block-image size-large"><a href="/wp-content/uploads/2025/06/image-4.png"><img decoding="async" width="1024" height="717" src="/wp-content/uploads/2025/06/image-4-1024x717.png" alt="" class="wp-image-14730" srcset="/wp-content/uploads/2025/06/image-4-1024x717.png 1024w, /wp-content/uploads/2025/06/image-4-300x210.png 300w, /wp-content/uploads/2025/06/image-4-768x538.png 768w, /wp-content/uploads/2025/06/image-4-1536x1076.png 1536w, /wp-content/uploads/2025/06/image-4-2048x1435.png 2048w, /wp-content/uploads/2025/06/image-4-400x280.png 400w, /wp-content/uploads/2025/06/image-4-856x600.png 856w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></figure>



<h3 class="wp-block-heading">Update the Signing config for release</h3>



<p>Let&#8217;s create a release configuration under <strong>signingConfigs</strong> like below.</p>



<pre class="wp-block-code"><code>release {
            if (project.hasProperty("KEYSTORE_PATH")) {
                storeFile file(KEYSTORE_PATH)
                storePassword KEYSTORE_PASSWORD
                keyAlias KEY_ALIAS
                keyPassword KEY_PASSWORD
            }
        }</code></pre>



<p>From the above code, the variables KEY_PASSWORD, KEY_ALIAS, KEYSTORE_PASSWORD, KEYSTORE_PATH will be set from the pipeline itself. This is to sign the files using our secure file from Azure DevOps.</p>



<p>As there is a separate signingConfig for release, let&#8217;s configure that. Update the release section under the buildTypes. </p>



<pre class="wp-block-code"><code>release {
            // Caution! In production, you need to generate your own keystore file.
            // see https://reactnative.dev/docs/signed-apk-android.
            signingConfig signingConfigs.release
            minifyEnabled enableProguardInReleaseBuilds
            // Enables resource shrinking.
            shrinkResources true
            proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
        }</code></pre>



<p>Make sure to set the minifyEnabled and shrinkResources to true as this will reduce the overall size of your app bundle and time to install the app. You can read more on the app optimization <a href="https://developer.android.com/topic/performance/app-optimization/enable-app-optimization">here</a>.</p>



<h3 class="wp-block-heading">Optional: Increase the memory during the build</h3>



<p>You may get the error below when you run your pipeline. </p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>Execution failed for task &#8216;:app:collectReleaseDependencies&#8217;. &gt; Java heap space</p>
</blockquote>



<p>To fix this, go to your gradle.properties and update the settings below.</p>



<pre class="wp-block-code"><code># Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx512m -XX:MaxMetaspaceSize=256m
org.gradle.jvmargs=-Xmx4g -XX:MaxMetaspaceSize=512m</code></pre>



<h2 class="wp-block-heading">Azure DevOps YAML </h2>



<p>As we have done the configurations, let&#8217;s start updating the YAML file by setting a name first.</p>



<pre class="wp-block-code"><code>name: $(date:yyyy).$(Month)$(rev:.r) </code></pre>



<p>Below is the full YAML file.</p>



<pre class="wp-block-code"><code># Android
# Build your Android project with Gradle.
# Add steps that test, sign, and distribute the APK, save build artifacts, and more:
# https://docs.microsoft.com/azure/devops/pipelines/languages/android
# https://learn.microsoft.com/en-us/azure/devops/pipelines/ecosystems/android
name: $(date:yyyy).$(Month)$(rev:.r)
trigger:
  - main
  - development

pool:
  vmImage: "macos-latest"

variables:
  - group: GooglePlayStore
  - name: KEYSTORE_FILE_NAME
    value: 'yourapp-gplaystore-key.keystore'

steps:
  - checkout: self
  - task: UseNode@1
    inputs:
      version: "22.x"
    displayName: "Use Node.js 22.x"
  - script: |
      ls -la $(Build.SourcesDirectory)
      ls -la $(Build.SourcesDirectory)/android
    displayName: "List Android Directory"
  - script: |
      npm install
    displayName: "npm install"
  - task: DownloadSecureFile@1
    name: keyStore
    displayName: "Download keystore from secure files"
    inputs:
      secureFile: $(KEYSTORE_FILE_NAME)
  - script: echo $(keyStore.secureFilePath)
    displayName: "Echo Keystore Path"
  - script: |
      ls -la $(Build.SourcesDirectory)/android
      ls -la $(Build.SourcesDirectory)/android/app
    displayName: "List Files"
  - task: Gradle@3
    displayName: "Gradle Build"
    inputs:
      workingDirectory: "$(Build.SourcesDirectory)/android"
      gradleWrapperFile: "android/gradlew"
      gradleOptions: "-Xmx3072m"
      publishJUnitResults: false
      testResultsFiles: "**/TEST-*.xml"
      tasks: "assembleRelease bundleRelease"
      options: "-PversionName=$(Build.BuildNumber) -PversionCode=$(Build.BuildId) -PKEYSTORE_PATH=$(keyStore.secureFilePath) -PKEYSTORE_PASSWORD=$(keystorePassword) -PKEY_ALIAS=$(keyAlias) -PKEY_PASSWORD=$(keyPassword)"
  - task: AndroidSigning@3
    inputs:
      apkFiles: "**/*.apk"
      apksignerKeystoreFile: "$(KEYSTORE_FILE_NAME)"
      apksignerKeystorePassword: "$(keystorePassword)"
      apksignerKeystoreAlias: "$(keyAlias)"
      apksignerKeyPassword: "$(keyPassword)"
      zipalign: false
  - task: CopyFiles@2
    displayName: "Copy APK Files"
    inputs:
      contents: "**/*.apk"
      targetFolder: "$(Build.ArtifactStagingDirectory)"
  - task: CopyFiles@2
    displayName: "Copy AAB App Bundle"
    inputs:
      sourceFolder: "android/app/build/outputs/bundle/release"
      contents: "**/*.aab"
      targetFolder: "$(Build.ArtifactStagingDirectory)/android/app/build/outputs/bundle/release"
  - task: PublishBuildArtifacts@1
    displayName: "Publish artifacts"
    inputs:
      pathToPublish: $(Build.ArtifactStagingDirectory)
      artifactName: yourapp</code></pre>



<p>We use the task <strong>DownloadSecureFile@1</strong> to download the keystore file and provide its path in the <strong>Gradle@3</strong> task. We set the name to keystore and use the property secureFilePath to get its path. </p>



<p>Note that in <strong>Gradle@3</strong> task even though you have set the workingDirectory as <strong>$(Build.SourcesDirectory)/android</strong>, you will need to se <strong>gradleWrapperFile </strong>as <strong>android/gradlew</strong>. Also check the options we pass to that task, that&#8217;s how we are setting the variables to the <strong>build.gradle</strong> files. The task value assembleRelease is to generate the APK file and bundleRelease is to create Android App Bundle (aab) for Google Play Store.</p>



<h1 class="wp-block-heading">Google Play Integrations</h1>



<p>Once the pipeline is run, you should be able to manually download the App bundle file from the artifacts. </p>



<figure class="wp-block-image size-large"><a href="/wp-content/uploads/2025/06/image-5.png"><img decoding="async" width="1024" height="888" src="/wp-content/uploads/2025/06/image-5-1024x888.png" alt="" class="wp-image-14736" srcset="/wp-content/uploads/2025/06/image-5-1024x888.png 1024w, /wp-content/uploads/2025/06/image-5-300x260.png 300w, /wp-content/uploads/2025/06/image-5-768x666.png 768w, /wp-content/uploads/2025/06/image-5-1536x1332.png 1536w, /wp-content/uploads/2025/06/image-5-400x347.png 400w, /wp-content/uploads/2025/06/image-5-692x600.png 692w, /wp-content/uploads/2025/06/image-5.png 1681w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></figure>



<p>You can upload to the Play store console for doing an internal release to test the app internally now. Select your application, click on the Test and release menu and then under Testing, select internal testing. This is where you can create a few internal users and upload your aab file. You can share the invite link with them. Please be noted that your internal tester would need to accept the request on their first visit to install the app. They should also be able to update the application from Play store when you release a new version.</p>



<figure class="wp-block-image size-large"><a href="/wp-content/uploads/2025/06/image-7.png"><img decoding="async" width="1024" height="851" src="/wp-content/uploads/2025/06/image-7-1024x851.png" alt="" class="wp-image-14742" srcset="/wp-content/uploads/2025/06/image-7-1024x851.png 1024w, /wp-content/uploads/2025/06/image-7-300x249.png 300w, /wp-content/uploads/2025/06/image-7-768x638.png 768w, /wp-content/uploads/2025/06/image-7-1536x1276.png 1536w, /wp-content/uploads/2025/06/image-7-400x332.png 400w, /wp-content/uploads/2025/06/image-7-722x600.png 722w, /wp-content/uploads/2025/06/image-7.png 1904w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></figure>



<h2 class="wp-block-heading">Service account and permission in Google Cloud Console</h2>



<p>Unfortunately the doc <a href="https://learn.microsoft.com/en-us/azure/devops/pipelines/ecosystems/android?view=azure-devops#release">here</a> and <a href="https://marketplace.visualstudio.com/items?itemName=ms-vsclient.google-play#user-content-google-play---release">here</a> are outdated and it took a while for me to configure this. You won&#8217;t be able to see the Setup and API access menu in <a href="https://play.google.com/console/">https://play.google.com/console/</a> as Google had moved them to another process. The new steps are, </p>



<h3 class="wp-block-heading"><strong>Create your service account in Google Cloud</strong></h3>



<ol start="1" class="wp-block-list">
<li>Go to <strong><a href="https://console.cloud.google.com/">Google Cloud Console</a> → IAM &amp; Admin → Service Accounts</strong></li>



<li>Create a new service account, grant it the <strong>Owner</strong> role (or at least Project > Editor)</li>



<li>Under the service account, add a <strong>JSON key</strong> and save the downloaded file. Please make sure to download this to a secure place, as this contains your key in it</li>
</ol>



<h3 class="wp-block-heading"><strong>Invite the service account in Play Console</strong></h3>



<ol start="1" class="wp-block-list">
<li>In the Play Console, go to <strong>Users and permissions</strong>.</li>



<li>Click <strong>Invite new user</strong>.</li>



<li>Paste the client_email from your JSON file (e.g. foo@bar.iam.gserviceaccount.com).</li>



<li>Assign your service account permissions:
<ul class="wp-block-list">
<li>Select your app</li>



<li>Give at least the permissions below
<ul class="wp-block-list">
<li>View app information (read-only)</li>



<li>Release to production, exclude devices, and use Play App Signing</li>



<li>Release apps to testing tracks</li>
</ul>
</li>
</ul>
</li>



<li>Send the invite, this will be auto approved</li>
</ol>



<h2 class="wp-block-heading">Create Azure DevOps service connection</h2>



<ol start="1" class="wp-block-list">
<li>Go to your AZDO project → <strong>Project settings → Service connections</strong>.</li>



<li>Create a <strong>New service connection → Google Play</strong>.</li>



<li>For <strong>service account email</strong>, use the JSON’s client_email; for <strong>private key</strong>, paste the entire key (include \n line breaks exactly)</li>



<li>Save it with the name yourapp-google-play. Make sure to replace yourapp with your app name.</li>
</ol>



<h2 class="wp-block-heading">Update the release YAML with GooglePlayRelease task</h2>



<p>The final step in the YAML file is to update it with the GooglePlayRelease task so that we can release app directly from the pipeline. </p>



<pre class="wp-block-code"><code>  - task: GooglePlayRelease@4
    inputs:
      serviceConnection: 'yourapp-google-play'
      applicationId: 'com.yourappid'
      action: 'SingleBundle'
      bundleFile: '$(Build.ArtifactStagingDirectory)/android/app/build/outputs/bundle/release/*.aab'
      track: 'internal'</code></pre>



<p>Finally, run your pipeline and if everything goes well, you should see that your pileline result as below.</p>



<figure class="wp-block-image size-large"><a href="/wp-content/uploads/2025/06/image-8.png"><img decoding="async" width="1024" height="517" src="/wp-content/uploads/2025/06/image-8-1024x517.png" alt="" class="wp-image-14745" srcset="/wp-content/uploads/2025/06/image-8-1024x517.png 1024w, /wp-content/uploads/2025/06/image-8-300x151.png 300w, /wp-content/uploads/2025/06/image-8-768x388.png 768w, /wp-content/uploads/2025/06/image-8-1536x776.png 1536w, /wp-content/uploads/2025/06/image-8-2048x1034.png 2048w, /wp-content/uploads/2025/06/image-8-400x202.png 400w, /wp-content/uploads/2025/06/image-8-1188x600.png 1188w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></figure>



<p>You should also be able to see the new version released for your internal test users in Google play console.</p>



<figure class="wp-block-image size-large"><a href="/wp-content/uploads/2025/06/image-9.png"><img decoding="async" width="1024" height="480" src="/wp-content/uploads/2025/06/image-9-1024x480.png" alt="" class="wp-image-14746" srcset="/wp-content/uploads/2025/06/image-9-1024x480.png 1024w, /wp-content/uploads/2025/06/image-9-300x141.png 300w, /wp-content/uploads/2025/06/image-9-768x360.png 768w, /wp-content/uploads/2025/06/image-9-1536x720.png 1536w, /wp-content/uploads/2025/06/image-9-2048x960.png 2048w, /wp-content/uploads/2025/06/image-9-400x188.png 400w, /wp-content/uploads/2025/06/image-9-1280x600.png 1280w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></figure>



<p>You can promote or increase the rollout of your application by following this <a href="https://learn.microsoft.com/en-us/azure/devops/pipelines/ecosystems/android?view=azure-devops#promote">doc</a>. </p>



<h1 class="wp-block-heading">About the Author</h1>



<p>I am yet another developer who is passionate about writing and sharing knowledge. I have written more than 500 blogs on my&nbsp;<a rel="noreferrer noopener" href="https://sibeeshpassion.com/" target="_blank">blog</a>. If you like this content, consider following me here,</p>



<ul class="wp-block-list">
<li><a href="https://github.com/SibeeshVenu">GitHub</a></li>



<li><a href="https://medium.com/@sibeeshvenu">medium</a></li>



<li><a href="https://twitter.com/sibeeshvenu">Twitter</a></li>
</ul>



<h1 class="wp-block-heading">Your turn. What do you think?</h1>



<p>Thanks a lot for reading. Did I miss anything that you may think is needed in this article? Could you find this post useful? Kindly do not forget to share your feedback.</p>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://sibeeshpassion.com/react-native-android-release-with-azure-devops-and-google-play-store-2/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Linux Azure Function Isolated Dot Net 9 YAML Template Deployment</title>
		<link>https://sibeeshpassion.com/linux-azure-function-isolated-dot-net-9-yaml-template-deployment/</link>
					<comments>https://sibeeshpassion.com/linux-azure-function-isolated-dot-net-9-yaml-template-deployment/#disqus_thread</comments>
		
		<dc:creator><![CDATA[SibeeshVenu]]></dc:creator>
		<pubDate>Sun, 27 Apr 2025 11:05:56 +0000</pubDate>
				<category><![CDATA[Azure]]></category>
		<category><![CDATA[Azure Function]]></category>
		<category><![CDATA[azure function release pipeline]]></category>
		<category><![CDATA[azure function worker process]]></category>
		<category><![CDATA[azure function yaml template and release]]></category>
		<category><![CDATA[dot net 9]]></category>
		<category><![CDATA[dotnet-isolated]]></category>
		<guid isPermaLink="false">https://sibeeshpassion.com/?p=14697</guid>

					<description><![CDATA[Introduction In this post, let&#8217;s see how we can deploy a dot net 9 isolated runtime model project to a Linux based Azure function. Prerequisites Creating the hosting plan It is not mandatory to create a hosting plan, as the resource will be auto created when you create the function, however it is recommended to create one as you can define your naming strategies and more controls. Here we are choosing the consumption plan. You can learn more about the hosting options Azure provides here. Below is the ARM template to create the consumption hosting plan. Creating the Azure function [&#8230;]]]></description>
										<content:encoded><![CDATA[
<h1 class="wp-block-heading">Introduction</h1>



<p>In this post, let&#8217;s see how we can deploy a dot net 9 isolated runtime model project to a Linux based Azure function.</p>



<h1 class="wp-block-heading"><strong>Prerequisites</strong></h1>



<h2 class="wp-block-heading"><strong>Creating the hosting plan</strong></h2>



<p>It is not mandatory to create a hosting plan, as the resource will be auto created when you create the function, however it is recommended to create one as you can define your naming strategies and more controls. Here we are choosing the consumption plan. You can learn more about the hosting options Azure provides <a href="https://learn.microsoft.com/en-us/azure/azure-functions/functions-scale">here</a>. Below is the ARM template to create the consumption hosting plan.</p>



<pre class="wp-block-code"><code>{
    "type": "Microsoft.Web/serverfarms",
    "apiVersion": "2024-04-01",
    "name": "&#91;parameters('funcAppServerFarmName')]",
    "location": "&#91;parameters('funcAppLocation')]",
    "kind": "functionapp",
    "sku": {
        "name": "Y1",
        "tier": "Dynamic"
    },
    "properties": {
        "computeMode": "Dynamic",
        "reserved": true
    }
}</code></pre>



<p><strong>Creating the Azure function</strong></p>



<p>Below is the ARM template to create the Azure function.</p>



<pre class="wp-block-code"><code>{
    "type": "Microsoft.Web/sites",
    "apiVersion": "2024-04-01",
    "name": "&#91;parameters('FuncName')]",
    "location": "&#91;parameters('funcAppLocation')]",
    "kind": "functionapp,linux",
    "identity": {
        "type": "SystemAssigned"
    },
    "properties": {
        "reserved": true,
        "alwaysOn": true,
        "serverFarmId": "&#91;resourceId('Microsoft.Web/serverfarms', parameters('funcAppServerFarmName'))]",
        "linuxFxVersion": "DOTNET-ISOLATED|9.0",
        "siteConfig": {
            "linuxFxVersion": "DOTNET-ISOLATED|9.0",
            "appSettings": &#91;
                {
                    "name": "AzureWebJobsStorage",
                    "value": "&#91;format('DefaultEndpointsProtocol=https;AccountName={0};EndpointSuffix={1};AccountKey={2}', parameters('StorageName'), environment().suffixes.storage, listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('StorageName')), '2022-05-01').keys&#91;0].value)]"
                },
                {
                    "name": "APPINSIGHTS_INSTRUMENTATIONKEY",
                    "value": "&#91;reference(resourceId('Microsoft.Insights/components', parameters('InsightsComponentName')), '2020-02-02').InstrumentationKey]"
                },
                {
                    "name": "FUNCTIONS_EXTENSION_VERSION",
                    "value": "~4"
                },
                {
                    "name": "FUNCTIONS_WORKER_RUNTIME",
                    "value": "dotnet-isolated"
                },
                {
                    "name": "linuxFxVersion",
                    "value": "DOTNET-ISOLATED|9.0"
                },
                {
                    "name": "WEBSITE_USE_PLACEHOLDER_DOTNETISOLATED",
                    "value": "1"
                },
                {
                    "name": "CosmosConnectionString",
                    "value": "&#91;concat('@Microsoft.KeyVault(SecretUri=', 'https://',parameters('KeyVaultName'),'.vault.azure.net/secrets/CosmosConnectionString)')]"
                }
            ],
            "minTlsVersion": "1.3"
        },
        "runtime": {
            "name": "dotnet-isolated"
        },
        "httpsOnly": true
    },
    "dependsOn": &#91;
        "&#91;resourceId('Microsoft.Insights/components', parameters('InsightsComponentName'))]",
        "&#91;resourceId('Microsoft.Web/serverfarms', parameters('funcAppServerFarmName'))]",
        "&#91;resourceId('Microsoft.Storage/storageAccounts', parameters('StorageName'))]"
    ]
}</code></pre>



<p>Please make sure to set the values linuxFxVersion, WEBSITE_USE_PLACEHOLDER_DOTNETISOLATED or you may get the error below when you deploy your code to the Azure function.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><em>Failed to sync triggers for function app &#8216;funcsintest03&#8217;. Error: BadRequest &#8211; Encountered an error (BadGateway) from host runtime. (CODE: 400)</em></p>
</blockquote>



<p>I have a detailed post on the error <a href="https://stackoverflow.com/a/79594377/5550507">here on Stack Overflow</a>. Here is a doc on <a href="https://learn.microsoft.com/en-us/azure/azure-functions/functions-infrastructure-as-code?pivots=consumption-plan&amp;tabs=json%2Clinux%2Cdevops">Automate resource deployment for your function app in Azure Functions</a>.</p>



<h1 class="wp-block-heading">Create Azure function application</h1>



<p>You can easily create the Azure function using the <a href="https://learn.microsoft.com/en-us/azure/azure-functions/functions-create-your-first-function-visual-studio">Visual Studio by following this post</a>. Please be noted that for my Azure function I am choosing my function to run in an isolated worker process to get the benefits like standard dependency injection, you can read more on this <a href="https://learn.microsoft.com/en-us/azure/azure-functions/dotnet-isolated-process-guide?tabs=hostbuilder%2Clinux">here</a>.</p>



<h1 class="wp-block-heading">Create the Azure DevOps pipelines</h1>



<p>Before we create the pipelines, let’s create the template YAML with the file name as func-template.yml so that we can use it for all of our environments like Dev, Test, Prod etc.</p>



<pre class="wp-block-code"><code>parameters:
  - name: azureSubscriptionServiceConnection
    type: string
  - name: functionAppName
    type: string
  - name: stageName
    type: string

stages:
  - stage: ${{ parameters.stageName }}_Stage
    displayName: Release stage ${{ parameters.stageName }}
    jobs:
      - job: ${{ parameters.stageName }}_Release
        displayName: ${{ parameters.stageName }}_Release
        pool:
          vmImage: "ubuntu-latest"
        steps:
          # Download an artifact named 'WebApp' to 'bin' in $(Build.SourcesDirectory)
          - task: DownloadPipelineArtifact@2
            inputs:
              artifactName: "drop"
              targetPath: $(Build.SourcesDirectory)/bin
          - task: AzureFunctionApp@2 # Add this at the end of your file
            inputs:
              azureSubscription: ${{ parameters.azureSubscriptionServiceConnection }}
              appType: functionAppLinux # This specifies a Linux-based function app
              #isFlexConsumption: true # Uncomment this line if you are deploying to a Flex Consumption app
              appName: ${{ parameters.functionAppName }}
              package: $(Build.SourcesDirectory)/bin/*.zip
              deploymentMethod: "zipDeploy" # 'auto' | 'zipDeploy' | 'runFromPackage'. Required. Deployment method. Default: auto.
              #Uncomment the next lines to deploy to a deployment slot
              #Note that deployment slots is not supported for Linux Dynamic SKU
              #deployToSlotOrASE: true
              #resourceGroupName: '&lt;RESOURCE_GROUP>'
              #slotName: '&lt;SLOT_NAME>'
              runtimeStack: 'DOTNET-ISOLATED|9.0'
</code></pre>



<p>Here we use the task AzureFunctionApp@2 task, you can learn more about that task <a href="https://learn.microsoft.com/en-us/azure/devops/pipelines/tasks/reference/azure-function-app-v2?view=azure-pipelines">here</a>. Next, create a YAML file func-template.yml with the contents below.</p>



<pre class="wp-block-code"><code>trigger:
  - main
stages:
  - stage: Build
    displayName: Build and push stage
    jobs:
      - job: Build
        displayName: Build
        pool:
          vmImage: "ubuntu-latest"
        steps:
          - task: UseDotNet@2
            inputs:
              packageType: "sdk"
              version: "9.0.x" # .NET 9 preview/stable depending on your needs
              installationPath: $(Agent.ToolsDirectory)/dotnet
          - checkout: self
          - script: |
              dotnet restore
              dotnet build --configuration Release
          - task: DotNetCoreCLI@2
            inputs:
              command: publish
              arguments: "--configuration Release --output publish_output"
              projects: "$(System.DefaultWorkingDirectory)/MyFunc.Func/MyFunc.Func.csproj"
              publishWebProjects: false
              modifyOutputPath: false
              zipAfterPublish: false
          - task: ArchiveFiles@2
            displayName: "Archive files"
            inputs:
              rootFolderOrFile: "$(System.DefaultWorkingDirectory)/publish_output"
              includeRootFolder: false
              archiveFile: "$(System.DefaultWorkingDirectory)/build$(Build.BuildId).zip"
          - task: PublishBuildArtifacts@1
            inputs:
              PathtoPublish: "$(System.DefaultWorkingDirectory)/build$(Build.BuildId).zip"
              artifactName: "drop"

  - template: func-template.yml
    parameters:
      azureSubscriptionServiceConnection: "MyFuncdevmi"
      functionAppName: "MyFuncfuncsindev03"
      stageName: "DEV"
  - template: func-template.yml
    parameters:
      azureSubscriptionServiceConnection: "MyFunctestmi"
      functionAppName: "MyFuncfuncsintest03"
      stageName: "TEST"
</code></pre>



<p>In the above YAML file, my function project name is MyFunc and I am using the MyFuncdevmi as the service connection to deploy the Azure function to the DEV environment MyFuncfuncsindev03 and MyFunctestmi to deploy to my TEST environment MyFuncfuncsintest03.</p>



<p>I am using managed identity to create those service connection. You can create a managed identity using the ARM template below.</p>



<pre class="wp-block-code"><code>{
    "type": "Microsoft.ManagedIdentity/userAssignedIdentities",
    "apiVersion": "2024-11-30",
    "name": "&#91;parameters('managedIdentityName')]",
    "location": "&#91;parameters('location')]",
    "tags": {
        "{customized property}": "string"
    }
}&nbsp; &nbsp; &nbsp;</code></pre>



<p>You can follow this doc to create the <a href="https://learn.microsoft.com/en-us/azure/devops/pipelines/library/connect-to-azure?view=azure-devops">service connection using the managed identity</a>.</p>



<h1 class="wp-block-heading">Create the pipeline using the YAMLs created</h1>



<p>Go to the Pipeline menu and click on New pipeline button. Select your Azure DevOps repository and click on the option Existing Azure Pipelines YAML file. </p>



<figure class="wp-block-image size-large"><a href="/wp-content/uploads/2025/04/image.png"><img decoding="async" width="1024" height="434" src="/wp-content/uploads/2025/04/image-1024x434.png" alt="" class="wp-image-14699" srcset="/wp-content/uploads/2025/04/image-1024x434.png 1024w, /wp-content/uploads/2025/04/image-300x127.png 300w, /wp-content/uploads/2025/04/image-768x325.png 768w, /wp-content/uploads/2025/04/image-1536x651.png 1536w, /wp-content/uploads/2025/04/image-2048x867.png 2048w, /wp-content/uploads/2025/04/image-400x169.png 400w, /wp-content/uploads/2025/04/image-1417x600.png 1417w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></figure>



<p>Choose the path to your release pipeline YAML file, not the template YAML file, and run your pipeline. If your pipeline is successful, you should be able to see the output as below.</p>



<figure class="wp-block-image size-large"><a href="/wp-content/uploads/2025/04/image-3.png"><img decoding="async" width="1024" height="364" src="/wp-content/uploads/2025/04/image-3-1024x364.png" alt="" class="wp-image-14704" srcset="/wp-content/uploads/2025/04/image-3-1024x364.png 1024w, /wp-content/uploads/2025/04/image-3-300x107.png 300w, /wp-content/uploads/2025/04/image-3-768x273.png 768w, /wp-content/uploads/2025/04/image-3-1536x546.png 1536w, /wp-content/uploads/2025/04/image-3-2048x728.png 2048w, /wp-content/uploads/2025/04/image-3-400x142.png 400w, /wp-content/uploads/2025/04/image-3-1689x600.png 1689w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></figure>



<figure class="wp-block-image size-large"><a href="/wp-content/uploads/2025/04/image-1.png"><img decoding="async" width="1024" height="270" src="/wp-content/uploads/2025/04/image-1-1024x270.png" alt="" class="wp-image-14700" srcset="/wp-content/uploads/2025/04/image-1-1024x270.png 1024w, /wp-content/uploads/2025/04/image-1-300x79.png 300w, /wp-content/uploads/2025/04/image-1-768x202.png 768w, /wp-content/uploads/2025/04/image-1-1536x404.png 1536w, /wp-content/uploads/2025/04/image-1-2048x539.png 2048w, /wp-content/uploads/2025/04/image-1-400x105.png 400w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></figure>



<h1 class="wp-block-heading">Conclusion</h1>



<p>In this post we have learned how to,</p>



<ul class="wp-block-list">
<li>create the Azure function and consumption hosting plan with dotnet isolated worker process</li>



<li>create the temple for the deploying the Azure function</li>



<li>create the release YAML using the template file</li>
</ul>



<h1 class="wp-block-heading">About the Author</h1>



<p>I am yet another developer who is passionate about writing and sharing knowledge. I have written more than 500 blogs on my&nbsp;<a rel="noreferrer noopener" href="https://sibeeshpassion.com/" target="_blank">blog</a>. If you like this content, consider following me here,</p>



<ul class="wp-block-list">
<li><a href="https://github.com/SibeeshVenu">GitHub</a></li>



<li><a href="https://medium.com/@sibeeshvenu">medium</a></li>



<li><a href="https://twitter.com/sibeeshvenu">Twitter</a></li>
</ul>



<h1 class="wp-block-heading">Your turn. What do you think?</h1>



<p>Thanks a lot for reading. Did I miss anything that you may think is needed in this article? Could you find this post useful? Kindly do not forget to share your feedback.</p>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://sibeeshpassion.com/linux-azure-function-isolated-dot-net-9-yaml-template-deployment/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Build, Deploy, Configure CI &#038;CD Your Static Website in 5 mins</title>
		<link>https://sibeeshpassion.com/build-deploy-configure-ci-cd-your-static-website-in-5-mins/</link>
					<comments>https://sibeeshpassion.com/build-deploy-configure-ci-cd-your-static-website-in-5-mins/#disqus_thread</comments>
		
		<dc:creator><![CDATA[SibeeshVenu]]></dc:creator>
		<pubDate>Sun, 30 Mar 2025 11:11:50 +0000</pubDate>
				<category><![CDATA[Azure]]></category>
		<category><![CDATA[azure static web app]]></category>
		<category><![CDATA[azure static web app custom domain configuration]]></category>
		<category><![CDATA[azure static web app deployment pipeline yaml]]></category>
		<category><![CDATA[azure static web app with azure devops]]></category>
		<category><![CDATA[azure swa]]></category>
		<guid isPermaLink="false">https://sibeeshpassion.com/?p=14675</guid>

					<description><![CDATA[If you have a static website that has contents like HTML, CSS and images and you would like to host them, you can do that in 5 mins with the help of Azure Static Web Apps. Some of the key benefits of static web app are globally distributed content without the need of CDN, free auto-rotated SSL certificate, API support with Azure function. Here in this post we will see how we can create, build, deploy the Azure Static Web app. Prerequisites Create Azure Static Web App Go to the Azure portal and select the static web app. Under the [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>If you have a static website that has contents like HTML, CSS and images and you would like to host them, you can do that in 5 mins with the help of Azure Static Web Apps. Some of the key benefits of static web app are globally distributed content without the need of CDN, free auto-rotated SSL certificate, API support with Azure function. Here in this post we will see how we can create, build, deploy the Azure Static Web app. </p>



<p></p>



<h1 class="wp-block-heading">Prerequisites</h1>



<ol class="wp-block-list">
<li>You must have a repository that has your static files</li>



<li>You must have access to Azure portal</li>
</ol>



<h1 class="wp-block-heading">Create Azure Static Web App</h1>



<p>Go to the Azure portal and select the static web app. Under the deployment settings, make sure you select the Azure devops repository where the static files are pushed. </p>



<figure class="wp-block-image size-large"><a href="/wp-content/uploads/2025/03/image-19.png"><img decoding="async" width="1024" height="595" src="/wp-content/uploads/2025/03/image-19-1024x595.png" alt="" class="wp-image-14677" srcset="/wp-content/uploads/2025/03/image-19-1024x595.png 1024w, /wp-content/uploads/2025/03/image-19-300x174.png 300w, /wp-content/uploads/2025/03/image-19-768x446.png 768w, /wp-content/uploads/2025/03/image-19-1536x892.png 1536w, /wp-content/uploads/2025/03/image-19-2048x1190.png 2048w, /wp-content/uploads/2025/03/image-19-400x232.png 400w, /wp-content/uploads/2025/03/image-19-1033x600.png 1033w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></figure>



<p>For the build preset, select one that suits your project, here I am selecting HTML. The app artefact location or output location is based on the preset that you select. For HTML it is &#8220;/&#8221;, you can learn more on that <a href="https://learn.microsoft.com/en-us/azure/static-web-apps/front-end-frameworks">here</a>. </p>



<p>When you click on the Review + Create button on the portal, the build and release pipeline will be created with YAML file that you can edit later.</p>



<p>You may get the error below when you click the Create button. </p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>Failed to create a Personal Access Token for this user in Azure DevOps. Please deploy your app using the &#8216;Other&#8217; deployment source instead of &#8216;Azure DevOps&#8217;. After the app is created, open it and follow the instructions to get the token and deploy your app.</p>
</blockquote>



<p>If that happens, as the error suggested, select the deployment source as Other and proceed. We will need to configure the deployment once the app is created.</p>



<p>You can also create the static web app using the ARM template, Bicep or Terraform. Read about that <a href="https://learn.microsoft.com/en-us/azure/templates/microsoft.web/staticsites?pivots=deployment-language-arm-template">here</a> and <a href="https://learn.microsoft.com/en-us/azure/static-web-apps/publish-azure-resource-manager?tabs=azure-cli">here</a>. </p>



<h1 class="wp-block-heading">Configure CI &amp; CD deployment</h1>



<p>Once the app is created, you can go to the URLs given for your app and you should see a start page as below. </p>



<figure class="wp-block-image size-large"><a href="/wp-content/uploads/2025/03/image-20.jpg"><img decoding="async" width="1024" height="691" src="/wp-content/uploads/2025/03/image-20-1024x691.jpg" alt="" class="wp-image-14678" srcset="/wp-content/uploads/2025/03/image-20-1024x691.jpg 1024w, /wp-content/uploads/2025/03/image-20-300x202.jpg 300w, /wp-content/uploads/2025/03/image-20-768x518.jpg 768w, /wp-content/uploads/2025/03/image-20-1536x1036.jpg 1536w, /wp-content/uploads/2025/03/image-20-2048x1382.jpg 2048w, /wp-content/uploads/2025/03/image-20-400x270.jpg 400w, /wp-content/uploads/2025/03/image-20-889x600.jpg 889w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></figure>



<p>Click on the Manage Deployment Token button under the overview pane and copy the deployment token. We will be setting this value as a secret in our pipeline later.</p>



<figure class="wp-block-image size-large"><a href="/wp-content/uploads/2025/03/image-20.png"><img decoding="async" width="1024" height="120" src="/wp-content/uploads/2025/03/image-20-1024x120.png" alt="" class="wp-image-14680" srcset="/wp-content/uploads/2025/03/image-20-1024x120.png 1024w, /wp-content/uploads/2025/03/image-20-300x35.png 300w, /wp-content/uploads/2025/03/image-20-768x90.png 768w, /wp-content/uploads/2025/03/image-20-1536x180.png 1536w, /wp-content/uploads/2025/03/image-20-2048x240.png 2048w, /wp-content/uploads/2025/03/image-20-400x47.png 400w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></figure>



<p>Go to your Auzre DevOps and click on the Pipelines. Click on the New pipleline and select your repository from Azure DevOps. In the configure tab, select Starter pipeline. Replace the content with the below codes. </p>



<p><a href="https://gist.github.com/SibeeshVenu/1c9eeb3a54ebb4bc6a240de46e1e4f61">https://gist.github.com/SibeeshVenu/1c9eeb3a54ebb4bc6a240de46e1e4f61</a></p>



<pre class="wp-block-code"><code>trigger:
  - main

pool:
  vmImage: ubuntu-latest

steps:
  - checkout: self
    submodules: true
  - task: AzureStaticWebApp@0
    inputs:
      app_location: '/' # App source code path relative to cwd
      # api_location: 'api' # Api source code path relative to cwd
      # output_location: 'public' # Built app content directory relative to app_location - optional
      # cwd: '$(System.DefaultWorkingDirectory)/myapp' # Working directory - optional
      azure_static_web_apps_api_token: $(deployment_token)</code></pre>



<p>Click Save and run, the pipeline will fail for the first time as we have not set the deployment_token varible in the pipeline yet. Go to the created pipeline and click on Edit, click on Variables and then click New variable. Set the variable name as deployment_token and paste the deloyment token we copied as the value. Remember to set the value as secret. There are many ways to set the secret for your pipelines, you can read about those <a href="https://learn.microsoft.com/en-us/azure/devops/pipelines/process/set-secret-variables?view=azure-devops&amp;tabs=yaml%2Cbash">here</a> and <a href="https://learn.microsoft.com/en-us/azure/devops/pipelines/process/variables?view=azure-devops&amp;tabs=yaml%2Cbatch">here</a>.</p>



<figure class="wp-block-image size-large"><a href="/wp-content/uploads/2025/03/image-21.png"><img decoding="async" width="802" height="1024" src="/wp-content/uploads/2025/03/image-21-802x1024.png" alt="" class="wp-image-14681" srcset="/wp-content/uploads/2025/03/image-21-802x1024.png 802w, /wp-content/uploads/2025/03/image-21-235x300.png 235w, /wp-content/uploads/2025/03/image-21-768x981.png 768w, /wp-content/uploads/2025/03/image-21-1203x1536.png 1203w, /wp-content/uploads/2025/03/image-21-400x511.png 400w, /wp-content/uploads/2025/03/image-21-470x600.png 470w, /wp-content/uploads/2025/03/image-21.png 1361w" sizes="(max-width: 802px) 100vw, 802px" /></a></figure>



<p>Run your pipeline again. This time, the pipeline should be successful and you should be able to load your Static web app with your contents now.</p>



<h1 class="wp-block-heading">Configure Custom Domain</h1>



<p>Goto your Static web app and then click on the Add a custom domain tile.</p>



<figure class="wp-block-image size-large"><a href="/wp-content/uploads/2025/03/image-22.png"><img decoding="async" width="1024" height="302" src="/wp-content/uploads/2025/03/image-22-1024x302.png" alt="" class="wp-image-14682" srcset="/wp-content/uploads/2025/03/image-22-1024x302.png 1024w, /wp-content/uploads/2025/03/image-22-300x89.png 300w, /wp-content/uploads/2025/03/image-22-768x227.png 768w, /wp-content/uploads/2025/03/image-22-1536x454.png 1536w, /wp-content/uploads/2025/03/image-22-400x118.png 400w, /wp-content/uploads/2025/03/image-22.png 1957w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></figure>



<p>Select the appropriate option as per your needs. I am selecting Custom domain on other DNS.</p>



<figure class="wp-block-image size-large"><a href="/wp-content/uploads/2025/03/image-23.png"><img decoding="async" width="1024" height="428" src="/wp-content/uploads/2025/03/image-23-1024x428.png" alt="" class="wp-image-14683" srcset="/wp-content/uploads/2025/03/image-23-1024x428.png 1024w, /wp-content/uploads/2025/03/image-23-300x125.png 300w, /wp-content/uploads/2025/03/image-23-768x321.png 768w, /wp-content/uploads/2025/03/image-23-1536x642.png 1536w, /wp-content/uploads/2025/03/image-23-400x167.png 400w, /wp-content/uploads/2025/03/image-23-1436x600.png 1436w, /wp-content/uploads/2025/03/image-23.png 1797w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></figure>



<p>Enter the domain and select the Hostname record type, here I am selecting CNAME.</p>



<figure class="wp-block-image size-large"><a href="/wp-content/uploads/2025/03/image-25.png"><img decoding="async" width="1024" height="527" src="/wp-content/uploads/2025/03/image-25-1024x527.png" alt="" class="wp-image-14686" srcset="/wp-content/uploads/2025/03/image-25-1024x527.png 1024w, /wp-content/uploads/2025/03/image-25-300x154.png 300w, /wp-content/uploads/2025/03/image-25-768x395.png 768w, /wp-content/uploads/2025/03/image-25-1536x790.png 1536w, /wp-content/uploads/2025/03/image-25-400x206.png 400w, /wp-content/uploads/2025/03/image-25-1167x600.png 1167w, /wp-content/uploads/2025/03/image-25.png 1674w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></figure>



<p>If you give the domain without www in it, you may get the below error. </p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>Request Envelope is invalid. Apex Domains must use dns-txt-token as the ValidationMethod.</p>
</blockquote>



<p>You can learn more about the custom domain <a href="https://learn.microsoft.com/en-us/azure/static-web-apps/custom-domain">here</a>. Copy the CNAME hostname record and add it to your DNS provider to confirm your domain ownership. It can take up to 48 or 72 hours for DNS entry changes to take effect. Once that period is over, you can come here and try to add the custom domain again. Once it is added you should see a Status as &#8220;Validated&#8221;. </p>



<p>If you want to add the custom domain without &#8220;www&#8221; in it, then you must add a TXT record with the host as &#8220;@&#8221; and value as the code generated in the static web app&#8217;s custom domain section in your domains DNS configuration. You can learn more <a href="https://learn.microsoft.com/en-us/azure/static-web-apps/custom-domain?wt.mc_id=azurestaticwebapps_inline_inproduct_general">here</a>.</p>



<p></p>



<h1 class="wp-block-heading">Learn More</h1>



<p>You can learn more about the Static Web App from the tutorials below.</p>



<ol class="wp-block-list">
<li><a href="https://devblogs.microsoft.com/devops/comparing-azure-static-web-apps-vs-azure-webapps-vs-azure-blob-storage-static-sites/">Comparing Azure Static Web Apps vs Azure WebApps vs Azure Blob Storage Static Sites</a></li>



<li><a href="https://learn.microsoft.com/en-us/azure/static-web-apps/get-started-portal?pivots=azure-devops&amp;tabs=vanilla-javascript">Quickstart: Build your first static web app</a></li>



<li><a href="https://azure.microsoft.com/en-us/pricing/details/app-service/static/#overview">Static Web Apps pricing</a></li>
</ol>



<h1 class="wp-block-heading">Conclusion</h1>



<p>In this post we have seen how easily we can creat an Azure static web app, how to deploy or configure CI &amp; CD with your new static web app, and how to configure the custom domain name to your static web app.</p>



<h1 class="wp-block-heading">About the Author</h1>



<p>I am yet another developer who is passionate about writing and sharing knowledge. I have written more than 500 blogs on my&nbsp;<a rel="noreferrer noopener" href="https://sibeeshpassion.com/" target="_blank">blog</a>. If you like this content, consider following me here,</p>



<ul class="wp-block-list">
<li><a href="https://github.com/SibeeshVenu">GitHub</a></li>



<li><a href="https://medium.com/@sibeeshvenu">medium</a></li>



<li><a href="https://twitter.com/sibeeshvenu">Twitter</a></li>
</ul>



<h1 class="wp-block-heading">Your turn. What do you think?</h1>



<p>Thanks a lot for reading. Did I miss anything that you may think is needed in this article? Could you find this post useful? Kindly do not forget to share your feedback.</p>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://sibeeshpassion.com/build-deploy-configure-ci-cd-your-static-website-in-5-mins/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Easily move data from one COSMOS DB to another</title>
		<link>https://sibeeshpassion.com/easily-move-data-from-one-cosmos-db-to-another/</link>
					<comments>https://sibeeshpassion.com/easily-move-data-from-one-cosmos-db-to-another/#disqus_thread</comments>
		
		<dc:creator><![CDATA[SibeeshVenu]]></dc:creator>
		<pubDate>Sun, 09 Mar 2025 10:26:30 +0000</pubDate>
				<category><![CDATA[Azure]]></category>
		<category><![CDATA[Cosmos DB]]></category>
		<category><![CDATA[Data Factory]]></category>
		<category><![CDATA[Azure Data Factory Copy Pipeline]]></category>
		<category><![CDATA[Copy data from one Cosmos DB to another]]></category>
		<category><![CDATA[Cosmos DB Data Move]]></category>
		<guid isPermaLink="false">https://sibeeshpassion.com/?p=14648</guid>

					<description><![CDATA[Introduction In this post, let&#8217;s discuss how easily we can move data from one cosmos database to another with the help of Azure data factory. An Azure data factory is a fully managed serverless data integration service, while it provides solutions for many use cases, today I am going to demonstrate to move data without writing a single line of code. Let&#8217;s get to it. Creating Azure data factory There are many ways to create Azure data factory Create Pipeline When you have ceated the Data factory, open that from the Azure portal, click on the Overview blade and click [&#8230;]]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">Introduction</h2>



<p>In this post, let&#8217;s discuss how easily we can move data from one cosmos database to another with the help of Azure data factory. An <a href="https://azure.microsoft.com/en-us/products/data-factory">Azure data factory</a> is a fully managed serverless data integration service, while it provides solutions for many use cases, today I am going to demonstrate to move data without writing a single line of code. Let&#8217;s get to it.</p>



<h2 class="wp-block-heading">Creating Azure data factory</h2>



<p>There are many ways to create Azure data factory</p>



<ol class="wp-block-list">
<li><a href="https://learn.microsoft.com/en-us/azure/data-factory/quickstart-create-data-factory">Create a data factory by using the Azure portal</a></li>



<li><a href="https://learn.microsoft.com/en-us/azure/data-factory/quickstart-create-data-factory-resource-manager-template">Create an Azure Data Factory using ARM template</a></li>
</ol>



<h2 class="wp-block-heading">Create Pipeline</h2>



<p>When you have ceated the Data factory, open that from the Azure portal, click on the Overview blade and click on the Launch Studio button. </p>



<figure class="wp-block-image size-large"><a href="/wp-content/uploads/2025/03/Launch-Azure-data-studio.jpg"><img decoding="async" width="1024" height="382" src="/wp-content/uploads/2025/03/Launch-Azure-data-studio-1024x382.jpg" alt="" class="wp-image-14653" srcset="/wp-content/uploads/2025/03/Launch-Azure-data-studio-1024x382.jpg 1024w, /wp-content/uploads/2025/03/Launch-Azure-data-studio-300x112.jpg 300w, /wp-content/uploads/2025/03/Launch-Azure-data-studio-768x286.jpg 768w, /wp-content/uploads/2025/03/Launch-Azure-data-studio-1536x573.jpg 1536w, /wp-content/uploads/2025/03/Launch-Azure-data-studio-2048x764.jpg 2048w, /wp-content/uploads/2025/03/Launch-Azure-data-studio-400x149.jpg 400w, /wp-content/uploads/2025/03/Launch-Azure-data-studio-1609x600.jpg 1609w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></figure>



<p>Cick on the Home page and then click on the Ingest. </p>



<figure class="wp-block-image size-large"><a href="/wp-content/uploads/2025/03/image-12.png"><img decoding="async" width="1024" height="620" src="/wp-content/uploads/2025/03/image-12-1024x620.png" alt="" class="wp-image-14665" srcset="/wp-content/uploads/2025/03/image-12-1024x620.png 1024w, /wp-content/uploads/2025/03/image-12-300x182.png 300w, /wp-content/uploads/2025/03/image-12-768x465.png 768w, /wp-content/uploads/2025/03/image-12-1536x930.png 1536w, /wp-content/uploads/2025/03/image-12-660x400.png 660w, /wp-content/uploads/2025/03/image-12-400x242.png 400w, /wp-content/uploads/2025/03/image-12-991x600.png 991w, /wp-content/uploads/2025/03/image-12.png 1546w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></figure>



<p>Under Properties, select Built-in copy task. You can select the task cadence otr task schedule as per your requirement. I am selecting &#8220;Run once now&#8221;.</p>



<figure class="wp-block-image size-large"><a href="/wp-content/uploads/2025/03/image-13.png"><img decoding="async" width="1024" height="962" src="/wp-content/uploads/2025/03/image-13-1024x962.png" alt="" class="wp-image-14666" srcset="/wp-content/uploads/2025/03/image-13-1024x962.png 1024w, /wp-content/uploads/2025/03/image-13-300x282.png 300w, /wp-content/uploads/2025/03/image-13-768x722.png 768w, /wp-content/uploads/2025/03/image-13-1536x1444.png 1536w, /wp-content/uploads/2025/03/image-13-400x376.png 400w, /wp-content/uploads/2025/03/image-13-638x600.png 638w, /wp-content/uploads/2025/03/image-13.png 1845w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></figure>



<h3 class="wp-block-heading">Select Source Dataset</h3>



<p>Under source tab, select your data source, I am selecting Azure CosmosDB for NoSQL. Under connection, +New connection. In the new pane, provide a name for your connection, and provide connection to the source either via a connection string from Azure subcription or Key Vault. </p>



<figure class="wp-block-image size-large"><a href="/wp-content/uploads/2025/03/image-14.png"><img decoding="async" width="882" height="1024" src="/wp-content/uploads/2025/03/image-14-882x1024.png" alt="" class="wp-image-14667" srcset="/wp-content/uploads/2025/03/image-14-882x1024.png 882w, /wp-content/uploads/2025/03/image-14-258x300.png 258w, /wp-content/uploads/2025/03/image-14-768x892.png 768w, /wp-content/uploads/2025/03/image-14-400x465.png 400w, /wp-content/uploads/2025/03/image-14-517x600.png 517w, /wp-content/uploads/2025/03/image-14.png 1003w" sizes="(max-width: 882px) 100vw, 882px" /></a></figure>



<p>The connection will be tested automatically and the tables/containers wil be loaded for you to select those are applicable. I am selecting all the tables and yes to checkbox &#8220;Export as-is to JSON files or Azure Cosmos DB collection&#8221;.</p>



<figure class="wp-block-image size-large"><a href="/wp-content/uploads/2025/03/image-15.png"><img decoding="async" width="861" height="1024" src="/wp-content/uploads/2025/03/image-15-861x1024.png" alt="" class="wp-image-14668" srcset="/wp-content/uploads/2025/03/image-15-861x1024.png 861w, /wp-content/uploads/2025/03/image-15-252x300.png 252w, /wp-content/uploads/2025/03/image-15-768x913.png 768w, /wp-content/uploads/2025/03/image-15-1292x1536.png 1292w, /wp-content/uploads/2025/03/image-15-400x475.png 400w, /wp-content/uploads/2025/03/image-15-505x600.png 505w, /wp-content/uploads/2025/03/image-15.png 1320w" sizes="(max-width: 861px) 100vw, 861px" /></a></figure>



<p>Click next, a filter window will appear, you can also preview your data in this section. </p>



<h3 class="wp-block-heading">Select Destination Data Store</h3>



<p>Under the destination pane, select the Destination type. I am selecting &#8220;Azure Cosmos DB for NoSQL&#8221; as I need to move data from Cosmos DB to another Cosmos DB. Create a connection for the destination by clicking the +New connection and proceed the steps we followed for creating the connection for the source. </p>



<p>Once the connection is validated, you will be able to see the copy activities from Source to Destination. Make sure to select the activities that are required. By default all will be selected. Click Next.</p>



<h4 class="wp-block-heading">Finalizing the task</h4>



<p>In the next step, name your task, if you prefer you can apply &#8220;Data consistency verification&#8221; that will enable logging. Select the advanced settings that are applicable to you. Select Next. You will be provided with the Summary, if everything is right, click Next. </p>



<p>It will create the datasets, creates the pipeline, and run the pipeline. You can Finish, Monitor or Edit your pipeline. </p>



<figure class="wp-block-image size-large"><a href="/wp-content/uploads/2025/03/image-16.png"><img decoding="async" width="1024" height="613" src="/wp-content/uploads/2025/03/image-16-1024x613.png" alt="" class="wp-image-14669" srcset="/wp-content/uploads/2025/03/image-16-1024x613.png 1024w, /wp-content/uploads/2025/03/image-16-300x180.png 300w, /wp-content/uploads/2025/03/image-16-768x460.png 768w, /wp-content/uploads/2025/03/image-16-1536x920.png 1536w, /wp-content/uploads/2025/03/image-16-2048x1226.png 2048w, /wp-content/uploads/2025/03/image-16-400x240.png 400w, /wp-content/uploads/2025/03/image-16-1002x600.png 1002w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></figure>



<p>If you ever want to see your pipeline again and edit, it will be under the Author pane and under the Pipeline section. </p>



<figure class="wp-block-image size-large"><a href="/wp-content/uploads/2025/03/image-17.png"><img decoding="async" width="1024" height="366" src="/wp-content/uploads/2025/03/image-17-1024x366.png" alt="" class="wp-image-14670" srcset="/wp-content/uploads/2025/03/image-17-1024x366.png 1024w, /wp-content/uploads/2025/03/image-17-300x107.png 300w, /wp-content/uploads/2025/03/image-17-768x275.png 768w, /wp-content/uploads/2025/03/image-17-1536x549.png 1536w, /wp-content/uploads/2025/03/image-17-400x143.png 400w, /wp-content/uploads/2025/03/image-17.png 1574w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></figure>



<p>For any pipeline, you can enable Auto save by enabling the Git integration. </p>



<figure class="wp-block-image size-large"><a href="/wp-content/uploads/2025/03/image-18.png"><img decoding="async" width="1024" height="1005" src="/wp-content/uploads/2025/03/image-18-1024x1005.png" alt="" class="wp-image-14671" srcset="/wp-content/uploads/2025/03/image-18-1024x1005.png 1024w, /wp-content/uploads/2025/03/image-18-300x295.png 300w, /wp-content/uploads/2025/03/image-18-768x754.png 768w, /wp-content/uploads/2025/03/image-18-400x393.png 400w, /wp-content/uploads/2025/03/image-18-611x600.png 611w, /wp-content/uploads/2025/03/image-18.png 1212w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></figure>



<p><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-cyan-blue-color">Verify that your Azure DevOps account is connected to the Microsoft Entra account, the Azure DevOps repository is in the Default Directory tenant, and that your current ADF user account has been added to the Azure DevOps organization.</mark></p>



<h2 class="wp-block-heading">Conclusion</h2>



<p>In this post we have seen how easily we can move data from one Azure Cosmos DB to another with the help of Azure Data factory and it&#8217;s in-built automation.</p>



<h2 class="wp-block-heading">About the Author</h2>



<p>I am yet another developer who is passionate about writing and sharing knowledge. I have written more than 500 blogs on my&nbsp;<a rel="noreferrer noopener" href="https://sibeeshpassion.com/" target="_blank">blog</a>. If you like this content, consider following me here,</p>



<ul class="wp-block-list">
<li><a href="https://github.com/SibeeshVenu">GitHub</a></li>



<li><a href="https://medium.com/@sibeeshvenu">medium</a></li>



<li><a href="https://twitter.com/sibeeshvenu">Twitter</a></li>
</ul>



<h2 class="wp-block-heading">Your turn. What do you think?</h2>



<p>Thanks a lot for reading. Did I miss anything that you may think is needed in this article? Could you find this post useful? Kindly do not forget to share your feedback.</p>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://sibeeshpassion.com/easily-move-data-from-one-cosmos-db-to-another/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>.NET 8 New and Efficient Way to Check IP is in Given IP Range</title>
		<link>https://sibeeshpassion.com/net-8-new-and-efficient-way-to-check-ip-is-in-given-ip-range/</link>
					<comments>https://sibeeshpassion.com/net-8-new-and-efficient-way-to-check-ip-is-in-given-ip-range/#disqus_thread</comments>
		
		<dc:creator><![CDATA[SibeeshVenu]]></dc:creator>
		<pubDate>Fri, 13 Oct 2023 09:54:45 +0000</pubDate>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[.NET8]]></category>
		<category><![CDATA[DOTNET8]]></category>
		<category><![CDATA[How to check IP is in IP Ranges]]></category>
		<category><![CDATA[IP in IP Ranges]]></category>
		<category><![CDATA[IPNetwork Class DOTNET8]]></category>
		<guid isPermaLink="false">https://sibeeshpassion.com/?p=14633</guid>

					<description><![CDATA[The .NET 8 has introduced a new type IPNetwork with a Contains method. It retruns true if the given IPAddress is part of the IP network. Otherwise, returns false. Here in this post, we will see how we can implement the same.]]></description>
										<content:encoded><![CDATA[
<p>In our <a href="https://sibeeshpassion.com/async-client-ip-safelist-for-dot-net/" data-type="link" data-id="https://sibeeshpassion.com/async-client-ip-safelist-for-dot-net/">last post</a> we have seen how we can restrict the access to your application by implementing IP restrictions using ActionFilterAttribute but we were checking the IP addresses and was missing a feature to support the IP Ranges. The good news is that the .NET 8 has a new and efficient way to do this. Here in this post, we will see how we can implement the same. Let&#8217;s begin. </p>



<h1 class="wp-block-heading">Source Code</h1>



<p>You can also see the codes in&nbsp;<a href="https://github.com/SibeeshVenu/DotNetIpFilter/" target="_blank" rel="noreferrer noopener">this repository</a>.</p>



<h1 class="wp-block-heading">Enablling .NET8 for Your Application</h1>



<p>As you might have already guessed, the first step is to download the .NET8 from <a href="https://dotnet.microsoft.com/en-us/download/dotnet/8.0" data-type="link" data-id="https://dotnet.microsoft.com/en-us/download/dotnet/8.0">here</a>. Let&#8217;s now change the TargetFramework in our both <code>DotNetIpFilter.csproj</code> and <code>DotNetIpFilter.Test.csproj</code> files. You can get the application code from the repositroy mentioned above. </p>



<pre class="wp-block-code"><code>&lt;TargetFramework&gt;net8.0&lt;/TargetFramework&gt;</code></pre>



<p>You will also need to update your <code>Microsoft.AspNetCore.OpenApi</code> package to .NET8.</p>



<h2 class="wp-block-heading">Enable Preview .NET 8 in Visual Studio 2022</h2>



<p>If you are trying to create a new application using Visual Studio 200, you may be missing an option to chose the .NET8 framework, to mak sure to get this option, do the following. </p>



<p>1. Update your Visual Studio 2022</p>



<p>2. Go to Tools -&gt; Manage Preview Features</p>


<div class="wp-block-image">
<figure class="aligncenter size-large is-resized"><a href="/wp-content/uploads/2023/10/image.png"><img decoding="async" width="696" height="1024" src="/wp-content/uploads/2023/10/image-696x1024.png" alt="" class="wp-image-14636" style="aspect-ratio:0.6796875;width:336px;height:auto" srcset="/wp-content/uploads/2023/10/image-696x1024.png 696w, /wp-content/uploads/2023/10/image-204x300.png 204w, /wp-content/uploads/2023/10/image-768x1130.png 768w, /wp-content/uploads/2023/10/image-400x588.png 400w, /wp-content/uploads/2023/10/image-408x600.png 408w, /wp-content/uploads/2023/10/image.png 1038w" sizes="(max-width: 696px) 100vw, 696px" /></a><figcaption class="wp-element-caption">.NET 8 Manage Preview Features</figcaption></figure>
</div>


<p>3. Select checkbox <code>Use preview of the .NET SDK (requires restart)</code></p>



<p>4. Make sure to restart after enabling this</p>


<div class="wp-block-image">
<figure class="aligncenter size-large is-resized"><a href="/wp-content/uploads/2023/10/image-1.png"><img decoding="async" width="1024" height="655" src="/wp-content/uploads/2023/10/image-1-1024x655.png" alt="" class="wp-image-14637" style="aspect-ratio:1.5633587786259542;width:550px;height:auto" srcset="/wp-content/uploads/2023/10/image-1-1024x655.png 1024w, /wp-content/uploads/2023/10/image-1-300x192.png 300w, /wp-content/uploads/2023/10/image-1-768x491.png 768w, /wp-content/uploads/2023/10/image-1-1536x982.png 1536w, /wp-content/uploads/2023/10/image-1-2048x1310.png 2048w, /wp-content/uploads/2023/10/image-1-400x256.png 400w, /wp-content/uploads/2023/10/image-1-938x600.png 938w" sizes="(max-width: 1024px) 100vw, 1024px" /></a><figcaption class="wp-element-caption">Use .NET Previews of the .NET SDK</figcaption></figure>
</div>


<h1 class="wp-block-heading">Use .NET8 Contains Method from <code>IPNetwork</code></h1>



<p>Let&#8217;s change our IpActionFilter.cs file code as below, to use the Contains method from .NET8 IPNetwork class. </p>



<script src="https://gist.github.com/SibeeshVenu/3700843ab923f85e192b0bded299327d.js"></script>



<p>In the code above the variable addressRange is a string that represents IP Address Range and ipAddressToCheck is the IP Address to check. The code for the IPNetwork is&nbsp;<a href="https://github.com/dotnet/aspnetcore/blob/main/src/Middleware/HttpOverrides/src/IPNetwork.cs">here</a>. You can learn more about this IPNetwork.Contains(IPAddress) method&nbsp;<a href="https://learn.microsoft.com/en-us/dotnet/api/system.net.ipnetwork.contains?view=net-8.0#system-net-ipnetwork-contains(system-net-ipaddress)">here</a>. Make sure to select the version .NET 8 for the doc. If you can&#8217;t use .Net 8, you can implement your own class by taking the code from&nbsp;<a href="https://github.com/dotnet/aspnetcore/blob/main/src/Middleware/HttpOverrides/src/IPNetwork.cs">here</a>.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>I also have a detailed StackOverflow answer <a href="https://stackoverflow.com/a/76928408/5550507" data-type="link" data-id="https://stackoverflow.com/a/76928408/5550507">here</a> on this topic.</p>
<cite>StackOverflow answer</cite></blockquote>



<h1 class="wp-block-heading">Test IP Filtering with Ranges</h1>



<p>Now, it is time to test our new implementation. Go to the <code>IpFilterService.cs</code> file and then edit the <code>GetAdminSafeIpList</code> method. Assign a few IP address ranges to the variable ipListArray, remember this is where you get a list of IP addresses and ranges from any of your middleware service using an async function. To make it simpler, I am assigning some of the IP addresses and ranges to that variable manually. </p>



<p>When you run the application you can see that the addresses and the ranges we set is getting validated in our <code>OnActionExecuting</code> method in <code>IpActionFilter.cs</code>. </p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><a href="/wp-content/uploads/2023/10/image-5.png"><img decoding="async" width="1024" height="548" src="/wp-content/uploads/2023/10/image-5-1024x548.png" alt="" class="wp-image-14641" srcset="/wp-content/uploads/2023/10/image-5-1024x548.png 1024w, /wp-content/uploads/2023/10/image-5-300x161.png 300w, /wp-content/uploads/2023/10/image-5-768x411.png 768w, /wp-content/uploads/2023/10/image-5-1536x822.png 1536w, /wp-content/uploads/2023/10/image-5-400x214.png 400w, /wp-content/uploads/2023/10/image-5-1121x600.png 1121w, /wp-content/uploads/2023/10/image-5.png 2000w" sizes="(max-width: 1024px) 100vw, 1024px" /></a><figcaption class="wp-element-caption">Compare IP Addresses and Ranges</figcaption></figure>
</div>


<p>The Contains method retruns true if the given IPAddress is part of the IP network. Otherwise, returns false.</p>


<div class="wp-block-image">
<figure class="aligncenter size-large is-resized"><a href="/wp-content/uploads/2023/10/image-3.png"><img decoding="async" width="1024" height="206" src="/wp-content/uploads/2023/10/image-3-1024x206.png" alt="" class="wp-image-14639" style="aspect-ratio:4.970873786407767;width:825px;height:auto" srcset="/wp-content/uploads/2023/10/image-3-1024x206.png 1024w, /wp-content/uploads/2023/10/image-3-300x60.png 300w, /wp-content/uploads/2023/10/image-3-768x155.png 768w, /wp-content/uploads/2023/10/image-3-1536x310.png 1536w, /wp-content/uploads/2023/10/image-3-400x81.png 400w, /wp-content/uploads/2023/10/image-3.png 1861w" sizes="(max-width: 1024px) 100vw, 1024px" /></a><figcaption class="wp-element-caption">Returns false when IP Address is not in Ranges</figcaption></figure>
</div>


<p>If you inspect the Contains method, you can see the code as below. This works with both IPV4 and IPV6. </p>



<script src="https://gist.github.com/SibeeshVenu/cd88ae1dcc383a6f1596e4a8eef270da.js"></script>



<h1 class="wp-block-heading">Conclusion</h1>



<p>In this post we have seen how easily we can check an IP address is in a given IP address ranges or not. Before this .Net8 release, we had to have our own implementaion, but now it is so easy and less codes. Less code is less maintenance, right. The .NET8 has many features just like this, checkout <a href="https://learn.microsoft.com/en-us/dotnet/core/whats-new/dotnet-8" data-type="link" data-id="https://learn.microsoft.com/en-us/dotnet/core/whats-new/dotnet-8">here</a>. </p>



<h1 class="wp-block-heading">About the Author</h1>



<p>I am yet another developer who is passionate about writing and sharing knowledge. I have written more than 500 blogs on my&nbsp;<a rel="noreferrer noopener" href="https://sibeeshpassion.com/" target="_blank">blog</a>. If you like this content, consider following me here,</p>



<ul class="wp-block-list">
<li><a href="https://github.com/SibeeshVenu">GitHub</a></li>



<li><a href="https://medium.com/@sibeeshvenu">medium</a></li>



<li><a href="https://twitter.com/sibeeshvenu">Twitter</a></li>
</ul>



<h1 class="wp-block-heading">Your turn. What do you think?</h1>



<p>Thanks a lot for reading. Did I miss anything that you may think is needed in this article? Could you find this post useful? Kindly do not forget to share your feedback.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://sibeeshpassion.com/net-8-new-and-efficient-way-to-check-ip-is-in-given-ip-range/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Async Client IP safelist for Dot NET</title>
		<link>https://sibeeshpassion.com/async-client-ip-safelist-for-dot-net/</link>
					<comments>https://sibeeshpassion.com/async-client-ip-safelist-for-dot-net/#disqus_thread</comments>
		
		<dc:creator><![CDATA[SibeeshVenu]]></dc:creator>
		<pubDate>Fri, 11 Aug 2023 13:58:43 +0000</pubDate>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Action filters in dot net 7]]></category>
		<category><![CDATA[Async call on Program file]]></category>
		<category><![CDATA[Async Client IP safelist for ASP.NET Core]]></category>
		<category><![CDATA[Async Startup]]></category>
		<category><![CDATA[IP Restrictions on Net 7]]></category>
		<category><![CDATA[Net 7 Web API]]></category>
		<guid isPermaLink="false">https://sibeeshpassion.com/?p=14617</guid>

					<description><![CDATA[Here, in this post we will see, how we can get the Safe List IP addresses asynchronously and add that to configure our ActionFilterAttribute and apply the same to the Web API to make sure that the unidentified requests gets 403 Forbidden.]]></description>
										<content:encoded><![CDATA[
<p>I have a .Net Web API project and I wanted to implement a mechanism via code to make sure that only certain IP addresses are allowed to call that API. We could do this by configuring the networking rules, Virtual Network, NSG implementations or even Azure App Access Restrictions if we host the Web API in an Azure App Service. However, the reason why I wanted to implement this via code is that the IP addresses list gets updated frequently and I wanted to make sure that there is very less maintenance on the service. Here, in this post we will see, how we can get the Safe List IP addresses asynchronously and add that to configure our ActionFilterAttribute and apply the same to the Web API to make sure that the unidentified requests gets 403 Forbidden.</p>



<h2 class="wp-block-heading">Create an IP Action Filter</h2>



<p>Before you do this, I assume that you already have the .Net Web API. For this post I am using .Net 7. Create a Services folder and then create a class IpActionFilter that is inherited from ActionFilterAttribute.</p>



<script src="https://gist.github.com/SibeeshVenu/cb8e6850d8809247847063ca44ec6dd7.js"></script>



<p>The implementation is a clone of this <a href="https://learn.microsoft.com/en-us/aspnet/core/security/ip-safelist?view=aspnetcore-7.0#action-filter">doc</a>. As you can see from that doc, there it the safe IP addresses list are static and is added to the App Settings manually. However in my scenario, I had to get this from an Async service call.</p>



<h1 class="wp-block-heading">Get the IP addresses from an Asyn service call</h1>



<p>We will create a new Service IpFilterService that implements IIpFilterService. Here we will mimic the async call to make this post more concrete. </p>



<script src="https://gist.github.com/SibeeshVenu/9a016d75d5c43173e1df9bf5f55a3b9b.js"></script>



<script src="https://gist.github.com/SibeeshVenu/dad0b02781b69c76515934e2bff88347.js"></script>



<h1 class="wp-block-heading">Async call to set the configuration</h1>



<p>If you just have a few IP addresses that can easily set in the App Settings. You can just add them manually as in this <a href="https://learn.microsoft.com/en-us/aspnet/core/security/ip-safelist?view=aspnetcore-7.0#ip-address-safelist">post</a>. As I wanted to update this list via an async service call, there are a few additional changes we must do. One of them is creating a Hosted Service that implements IHostedService and add that to the builder using builder.Services.AddHostedService. Let&#8217;s create IpHostedService. </p>



<script src="https://gist.github.com/SibeeshVenu/21bc246fddc07aad9b04ded1f02b4900.js"></script>



<p>As you can see from the code above, we are setting the AdminSafeIpList configuration to our App Settings via the code. Now all we need to add is to add this to the builder. </p>



<h1 class="wp-block-heading">Configure the builder</h1>



<p>To make sure that the AdminSafeIpList is updated to the App Settings, we will need to add our IpHostedService as a HostedService. You can learn more about this service <a href="https://learn.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-7.0&amp;tabs=visual-studio">here</a>. The code for Program.cs after this changes is below. </p>



<script src="https://gist.github.com/SibeeshVenu/a857e6b16005eb36b8161bfc000fdaf8.js"></script>



<p>So we are passing the AdminSafeIpList to the IpActionFilter. </p>



<h1 class="wp-block-heading">Enable IpActionFilter as a ServiceFilter</h1>



<p>As we have implemented the action filter and other required services, we now can add the IpActionFilter as a ServiceFilter in the controller or the actions. Add the code [ServiceFilter(typeof(IpActionFilter))] to top of controller or actions. </p>



<script src="https://gist.github.com/SibeeshVenu/9412bd9798bf78fc3d1ae62abdc61e50.js"></script>



<h1 class="wp-block-heading">Finally, Add some unit tests</h1>



<p>Let&#8217;s try to add some unit tests for our IpActionFilter.</p>



<script src="https://gist.github.com/SibeeshVenu/a92f899949943b044acc644ae3a118fa.js"></script>



<h1 class="wp-block-heading">Output</h1>



<p>Let&#8217;s build and run our API. You should see the preceeding response. </p>



<p><strong>With External IPs:</strong></p>



<figure class="wp-block-image size-large"><a href="/wp-content/uploads/2023/08/403-Forbidden-Result.png"><img decoding="async" width="1024" height="607" src="/wp-content/uploads/2023/08/403-Forbidden-Result-1024x607.png" alt="" class="wp-image-14619" srcset="/wp-content/uploads/2023/08/403-Forbidden-Result-1024x607.png 1024w, /wp-content/uploads/2023/08/403-Forbidden-Result-300x178.png 300w, /wp-content/uploads/2023/08/403-Forbidden-Result-768x455.png 768w, /wp-content/uploads/2023/08/403-Forbidden-Result-400x237.png 400w, /wp-content/uploads/2023/08/403-Forbidden-Result-1012x600.png 1012w, /wp-content/uploads/2023/08/403-Forbidden-Result.png 1255w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></figure>



<p><strong>With Internal IPs:</strong></p>



<figure class="wp-block-image size-large is-resized"><a href="/wp-content/uploads/2023/08/Without-IP-restrictions.png"><img decoding="async" src="/wp-content/uploads/2023/08/Without-IP-restrictions-839x1024.png" alt="" class="wp-image-14620" style="width:840px;height:1024px" width="840" height="1024" srcset="/wp-content/uploads/2023/08/Without-IP-restrictions-839x1024.png 839w, /wp-content/uploads/2023/08/Without-IP-restrictions-246x300.png 246w, /wp-content/uploads/2023/08/Without-IP-restrictions-768x937.png 768w, /wp-content/uploads/2023/08/Without-IP-restrictions-400x488.png 400w, /wp-content/uploads/2023/08/Without-IP-restrictions-492x600.png 492w, /wp-content/uploads/2023/08/Without-IP-restrictions.png 846w" sizes="(max-width: 840px) 100vw, 840px" /></a></figure>



<h1 class="wp-block-heading">Source Code</h1>



<p>You can also see the codes in&nbsp;<a href="https://github.com/SibeeshVenu/DotNetIpFilter/" target="_blank" rel="noreferrer noopener">this repository</a>.</p>



<h1 class="wp-block-heading">Conclusion</h1>



<p>Here in this post we have seen,</p>



<p>1. How we can restrict the accesse to our Web APIs by providing the Safe IP addresses list</p>



<p>2. How to create a new Action Filter and use that for Controllers</p>



<p>3. One of the challenge was to get the IP Address safe list from an Async service call and update the App Settings. </p>



<h1 class="wp-block-heading">About the Author</h1>



<p>I am yet another developer who is passionate about writing and video creation. I have written more than 500 blogs on my&nbsp;<a rel="noreferrer noopener" href="https://sibeeshpassion.com/" target="_blank">blog</a>. If you like this content, consider following me here,</p>



<ul class="wp-block-list">
<li><a href="https://github.com/SibeeshVenu">GitHub</a></li>



<li><a href="https://medium.com/@sibeeshvenu">medium</a></li>



<li><a href="https://twitter.com/sibeeshvenu">Twitter</a></li>
</ul>



<h1 class="wp-block-heading">Your turn. What do you think?</h1>



<p>Thanks a lot for reading. Did I miss anything that you may think is needed in this article? Could you find this post useful? Kindly do not forget to share your feedback.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://sibeeshpassion.com/async-client-ip-safelist-for-dot-net/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Post Messages to Microsoft Teams Using Python</title>
		<link>https://sibeeshpassion.com/post-messages-to-microsoft-teams-using-python/</link>
					<comments>https://sibeeshpassion.com/post-messages-to-microsoft-teams-using-python/#disqus_thread</comments>
		
		<dc:creator><![CDATA[SibeeshVenu]]></dc:creator>
		<pubDate>Sat, 01 Oct 2022 14:34:39 +0000</pubDate>
				<category><![CDATA[Azure]]></category>
		<category><![CDATA[Azure Key Vault]]></category>
		<category><![CDATA[Microsoft teams]]></category>
		<category><![CDATA[Microsoft Teams Webhook with Python]]></category>
		<category><![CDATA[Send message to Microsoft Teams]]></category>
		<category><![CDATA[Teams Python Client]]></category>
		<category><![CDATA[Teams Webhook]]></category>
		<guid isPermaLink="false">https://sibeeshpassion.com/?p=14592</guid>

					<description><![CDATA[Most of us uses Microsoft Teams on a daily basis, and we post a lot of messages, chats, contents to the platform. However there are times that you may need to post these contents automatically. Here in this post, we will see how we can post content to channel in Microsoft Teams using Python. Let's get started. ]]></description>
										<content:encoded><![CDATA[
<p>Most of us uses Microsoft Teams on a daily basis, and we post a lot of messages, chats, contents to the platform. However there are times that you may need to post these contents automatically. Here in this post, we will see how we can post content to channel in Microsoft Teams using Python. Let&#8217;s get started. </p>



<h1 class="wp-block-heading">Prerequisites</h1>



<ol class="wp-block-list"><li>You will need Python installed on your machine</li><li>You will need to create a Team and a channel in the Team</li></ol>



<h1 class="wp-block-heading">Setting up a channel</h1>



<h2 class="wp-block-heading">Creating a channel</h2>



<p>You will need to <a rel="noreferrer noopener" href="https://support.microsoft.com/en-us/office/create-a-team-from-scratch-174adf5f-846b-4780-b765-de1a0a737e2b" target="_blank">set up Teams before</a> you create a channel, and if you have enough access, it is an easy thing to do. Once the Team is ready to use, you can either use one of the existing channel, or create a new one from the context menu. </p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><a href="/wp-content/uploads/2022/10/image.png"><img decoding="async" width="303" height="509" src="/wp-content/uploads/2022/10/image.png" alt="" class="wp-image-14594" srcset="/wp-content/uploads/2022/10/image.png 303w, /wp-content/uploads/2022/10/image-179x300.png 179w" sizes="(max-width: 303px) 100vw, 303px" /></a><figcaption>Teams Context Menu</figcaption></figure>
</div>


<h2 class="wp-block-heading">Setting up the connector</h2>



<p>When you have decided which channel to use, click on the three dot on the right-side of your channel name, and then click on the Connectors and then search for the connector &#8220;Incoming Webhook&#8221; and then click on the button &#8220;Add&#8221;. </p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>The above process might take a few minutes. If you are unable to perform this, you can try using <a href="https://teams.microsoft.com/" target="_blank" rel="noreferrer noopener">the web version of Microsoft Teams</a>.</p><cite>Use of web verstion of Microsoft Teams</cite></blockquote>



<p>The above step will add the connector to your Teams, so that you can start configuring your Webhook. Click on the Configure button.</p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><a href="/wp-content/uploads/2022/10/image-1.png"><img decoding="async" width="1024" height="196" src="/wp-content/uploads/2022/10/image-1-1024x196.png" alt="" class="wp-image-14595" srcset="/wp-content/uploads/2022/10/image-1-1024x196.png 1024w, /wp-content/uploads/2022/10/image-1-300x57.png 300w, /wp-content/uploads/2022/10/image-1-768x147.png 768w, /wp-content/uploads/2022/10/image-1.png 1129w" sizes="(max-width: 1024px) 100vw, 1024px" /></a><figcaption>Configure Button</figcaption></figure>
</div>


<p>Provide a meaningful name for your Webhook and upload an image if required. Finally click on the Create button. A unique Url will be generated for your Webhook. Copy the Url and save it somewhere, we will later add this to <a rel="noreferrer noopener" href="https://sibeeshpassion.com/tag/azure-key-vault/" target="_blank">Azure Key Vault</a> and use from there. Click on the Done button. Your Webhook now should be shown as configured. </p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><a href="/wp-content/uploads/2022/10/image-2.png"><img decoding="async" width="1024" height="214" src="/wp-content/uploads/2022/10/image-2-1024x214.png" alt="" class="wp-image-14596" srcset="/wp-content/uploads/2022/10/image-2-1024x214.png 1024w, /wp-content/uploads/2022/10/image-2-300x63.png 300w, /wp-content/uploads/2022/10/image-2-768x161.png 768w, /wp-content/uploads/2022/10/image-2.png 1147w" sizes="(max-width: 1024px) 100vw, 1024px" /></a><figcaption>Webhook Configured</figcaption></figure>
</div>


<h1 class="wp-block-heading">Post Message Using the Connector</h1>



<h2 class="wp-block-heading">Setting up Azure Key Vault</h2>



<p>Configuring the Azure Key Vault is as easy as you set up any other Azure Resource. You may get the steps required from <a rel="noreferrer noopener" href="https://sibeeshpassion.com/why-not-secure-your-keys-and-secrets-asp-net-core-with-azure-key-vault-integration/" target="_blank">this post</a> or <a rel="noreferrer noopener" href="https://learn.microsoft.com/en-us/azure/key-vault/general/overview" target="_blank">this</a>. Add a new secret and paste the Webhook Url value you copied earlier. </p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>Make sure that you had set up the Access Policies on your Azure Key vault.</p><cite>Access Policy</cite></blockquote>



<p>Copy your Azure Key Vault name and the Secret name, we will use this in our Python function. </p>



<h2 class="wp-block-heading">Setting up Python Application</h2>



<p>Let&#8217;s set up our Python application. Create a directory msteams-webhook and create a file <strong>requirements.txt</strong> with the preceeding contents. </p>



<pre class="wp-block-code"><code>pymsteams&#91;async]
azure-identity
azure-keyvault-secrets</code></pre>



<p>Now run the commands below to create a virtual environment, activate the environment and then install the requirements in our environment. If you get a message like &#8220;WARNING: You are using pip version 19.2.3, however version 22.2.2 is available.&#8221;, you can upgrade pip by running the command <code>python -m pip install --upgrade pip</code></p>



<pre class="wp-block-code"><code>py -m venv .venv
.\.venv\Scripts\activate
py -m pip install -r requirements.txt</code></pre>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>You can learn more abou the Virtual Environment <a rel="noreferrer noopener" href="https://docs.python.org/3/library/venv.html" target="_blank">here</a>.</p><cite>Python Virtual Envrronment</cite></blockquote>



<h2 class="wp-block-heading">Get the Secret from Azure Key Vault</h2>



<p>Let&#8217;s create a new Python file <strong>keyvault_helper.py</strong> with the codes below. </p>



<script src="https://gist.github.com/SibeeshVenu/ce578e01a22000e430d92bd645ae95ea.js"></script>



<h2 class="wp-block-heading">Send Message to Teams Channel</h2>



<p>To send a message to the Teams channel, we are going to use a package pymsteams. This has been already added to our requirements file. Let&#8217;s create a file <strong>notify_teams.py</strong> with the codes below. </p>



<script src="https://gist.github.com/SibeeshVenu/f7262bb8a22c7e84041e16b3f71df7f7.js"></script>



<p>As we have all the set up done, let&#8217;s create main.py file with the codes below to start sending the messages to the Teams channel. </p>



<script src="https://gist.github.com/SibeeshVenu/62f000341b6284d2b92e1c0266647908.js"></script>



<p>Before you run the main file, make sure that you have logged in to the terminal using az login with the account that you had set the access policy in your azure key vault. We can also set this access policies by using a managed identity, or a service principal, so that we can use it for more production scenarios. But for this post, let&#8217;s stick with a user account. </p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>If you get the error,  <code>VisualStudioCodeCredential: The current credential is not configured to acquire tokens for tenant</code> or <code>SharedTokenCacheCredential: The current credential is not configured to acquire tokens for tenant</code> you can set the values  <code>exclude_shared_token_cache_credential=True</code> or <code>exclude_visual_studio_code_credential=True</code> when you get tokens using <code>DefaultAzureCredential</code> in your <code>get_key_vault_secret</code> function in <code>keyvault_helper.py</code> file. </p><cite>Keyvault Error</cite></blockquote>


<div class="wp-block-image">
<figure class="aligncenter size-large"><a href="/wp-content/uploads/2022/10/image-3.png"><img decoding="async" width="1024" height="201" src="/wp-content/uploads/2022/10/image-3-1024x201.png" alt="" class="wp-image-14598" srcset="/wp-content/uploads/2022/10/image-3-1024x201.png 1024w, /wp-content/uploads/2022/10/image-3-300x59.png 300w, /wp-content/uploads/2022/10/image-3-768x150.png 768w, /wp-content/uploads/2022/10/image-3.png 1302w" sizes="(max-width: 1024px) 100vw, 1024px" /></a><figcaption>default.py file from Azure Identity</figcaption></figure>
</div>


<p>By this time, we can hope that you will be able to get the secret from the key vault and now we can execute <code>py .\main.py</code> file. Once the file is executed, you should get a response in your cli as preceding. </p>



<pre class="wp-block-code"><code>{"version":"1.1","content":{"headers":&#91;{"key":"Content-Type","value":&#91;"text/plain; charset=utf-8"]}]},"statusCode":200,"reasonPhrase":"OK","headers":&#91;],"trailingHeaders":&#91;],"requestMessage":null,"isSuccessStatusCode":true}</code></pre>



<p>You should also get a message on your Teams channel.</p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><a href="/wp-content/uploads/2022/10/image-4.png"><img decoding="async" width="1024" height="175" src="/wp-content/uploads/2022/10/image-4-1024x175.png" alt="" class="wp-image-14599" srcset="/wp-content/uploads/2022/10/image-4-1024x175.png 1024w, /wp-content/uploads/2022/10/image-4-300x51.png 300w, /wp-content/uploads/2022/10/image-4-768x131.png 768w, /wp-content/uploads/2022/10/image-4-1536x263.png 1536w, /wp-content/uploads/2022/10/image-4-2048x350.png 2048w" sizes="(max-width: 1024px) 100vw, 1024px" /></a><figcaption>Message in Teams Channel</figcaption></figure>
</div>


<h1 class="wp-block-heading">Source Code</h1>



<p>You can also see the codes in <a href="https://github.com/SibeeshVenu/msteams-webhook-py" target="_blank" rel="noreferrer noopener">this repository</a>. </p>



<h1 class="wp-block-heading">About the Author</h1>



<p>I am yet another developer who is passionate about writing and video creation. I have written more than 500 blogs on my <a rel="noreferrer noopener" href="https://sibeeshpassion.com/" target="_blank">blog</a>. If you like this content, consider following me here,</p>



<ul class="wp-block-list"><li><a href="https://github.com/SibeeshVenu">GitHub</a></li><li><a href="https://medium.com/@sibeeshvenu">medium</a></li><li><a href="https://twitter.com/sibeeshvenu">Twitter</a></li></ul>



<h1 class="wp-block-heading">Your turn. What do you think?</h1>



<p>Thanks a lot for reading. Did I miss anything that you may think is needed in this article? Could you find this post useful? Kindly do not forget to share your feedback.</p>



<p>Kindest Regards</p>



<p>Sibeesh Venu</p>
]]></content:encoded>
					
					<wfw:commentRss>https://sibeeshpassion.com/post-messages-to-microsoft-teams-using-python/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Get Azure Blob Storage Blob Metadata Using PowerShell</title>
		<link>https://sibeeshpassion.com/get-azure-blob-storage-blob-metadata-using-powershell/</link>
					<comments>https://sibeeshpassion.com/get-azure-blob-storage-blob-metadata-using-powershell/#disqus_thread</comments>
		
		<dc:creator><![CDATA[SibeeshVenu]]></dc:creator>
		<pubDate>Fri, 20 May 2022 16:15:54 +0000</pubDate>
				<category><![CDATA[Azure]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Azure Storage]]></category>
		<category><![CDATA[Get blob metadata using PowerShell]]></category>
		<category><![CDATA[powershell]]></category>
		<guid isPermaLink="false">https://sibeeshpassion.com/?p=14572</guid>

					<description><![CDATA[Here we will see how you can get the metadata of each blob available in your Azure storage account using PowerShell.]]></description>
										<content:encoded><![CDATA[
<p>This is going to be a quick blog post. Here we will see how you can get the metadata of each blob available in your Azure storage account using PowerShell. Here I assume that you have access to your storage account and you will be asked to log in. Let&#8217;s get started. </p>



<h2 class="wp-block-heading">PowerShell command to get the metadata</h2>



<p><a href="https://gist.github.com/SibeeshVenu/a735db3439ca50305a5141ab83d26892" target="_blank" rel="noreferrer noopener">Here</a> is the command to get the metadata of all of your blobs in your storage account. </p>



<script src="https://gist.github.com/SibeeshVenu/a735db3439ca50305a5141ab83d26892.js"></script>



<p>Set your execution policy to Process if you get any policy errors. </p>



<pre class="wp-block-code"><code>Set-ExecutionPolicy -ExecutionPolicy ByPass -Scope Process</code></pre>



<p>If you get an authorization error as follows, make sure to add a role assignment of <strong>Storage Blob Data Contributor</strong>. You can do this via Access Control (IAM) of your storage account. Read more about this role <a href="https://docs.microsoft.com/en-us/azure/storage/blobs/assign-azure-role-data-access?tabs=portal" target="_blank" rel="noreferrer noopener">here</a>.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>PowerShell AuthorizationPermissionMismatch Error</p><cite>Get-AzStorageContainer : This request is not authorized to perform this operation using this permission.<br>RequestId:405a7e1a-f01e-004f-3acd-6a1168000000<br>Time:2022-05-18T15:38:30.5034936Z<br>Status: 403 (This request is not authorized to perform this operation using this permission.)<br>ErrorCode: AuthorizationPermissionMismatch<br>Content:<br>&lt;?xml version=&#8221;1.0&#8243; encoding=&#8221;utf-8&#8243;?&gt;&lt;Error&gt;&lt;Code&gt;AuthorizationPermissionMismatch&lt;/Code&gt;&lt;Message&gt;This request is not authorized to perform this operation using<br>this permission.</cite></blockquote>



<p>Once you add the role, you can try running your PowerShell command after a few minutes. Please make sure to provide the values to the variables <strong>$containerName, $subscriptionid, $storageAccName</strong>. Happy coding with PowerShell!</p>



<h2 class="wp-block-heading">About the Author</h2>



<p>I am yet another developer who is passionate about writing and video creation. I have written close to 500 blogs on my&nbsp;<a rel="noreferrer noopener" href="https://sibeeshpassion.com/" target="_blank">blog</a>. If you like this content, consider following me here,</p>



<ul class="wp-block-list"><li><a href="https://github.com/SibeeshVenu">GitHub</a></li><li><a href="https://medium.com/@sibeeshvenu">medium</a></li><li><a href="https://twitter.com/sibeeshvenu">Twitter</a></li></ul>



<h2 class="wp-block-heading">Your turn. What do you think?</h2>



<p>Thanks a lot for reading. Did I miss anything that you may think is needed in this article? Could you find this post useful? Kindly do not forget to share your feedback.</p>



<p>Kindest Regards</p>



<p>Sibeesh Venu</p>
]]></content:encoded>
					
					<wfw:commentRss>https://sibeeshpassion.com/get-azure-blob-storage-blob-metadata-using-powershell/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Deploy .net 6 App to Azure from Azure DevOps using Pipelines</title>
		<link>https://sibeeshpassion.com/deploy-net-6-app-to-azure-from-azure-devops-using-pipelines/</link>
					<comments>https://sibeeshpassion.com/deploy-net-6-app-to-azure-from-azure-devops-using-pipelines/#disqus_thread</comments>
		
		<dc:creator><![CDATA[SibeeshVenu]]></dc:creator>
		<pubDate>Wed, 15 Dec 2021 14:47:13 +0000</pubDate>
				<category><![CDATA[Azure]]></category>
		<category><![CDATA[.net 6]]></category>
		<category><![CDATA[Azure DevOps]]></category>
		<guid isPermaLink="false">https://sibeeshpassion.com/?p=14537</guid>

					<description><![CDATA[Working with both Azure and Azure DevOps is always fun, and the possibilities of automation are endless. I have written many articles on these topics and you can read them here. As you all know that the .net6 is been a talk in the market and I can't wait to try out things there. Here in this post, we will see how to use the Azure DevOps pipeline to build, restore and deploy the .net6 application to Azure Web App Service.]]></description>
										<content:encoded><![CDATA[
<p>Working with both Azure and Azure DevOps is always fun, and the possibilities of automation are endless. I have written many articles on these topics and you can read them <a rel="noreferrer noopener" href="https://sibeeshpassion.com/category/azure/" target="_blank">here</a>. As you all know that the .net6 is been a talk in the market and I can&#8217;t wait to try out things there. Here in this post, we will see how to use the Azure DevOps pipeline to build, restore and deploy the .net6 application to Azure Web App Service. Let&#8217;s get started. </p>



<p>At this point, I will assume that you have a .net6 application, Azure Web App Service, and Azure DevOps project with permission to configure the Pipeline and to add a new service connection to the Azure Resource Group. If you are not sure about how to configure the Service Connection to the Azure Resource Group, <a href="https://sibeeshpassion.com/azure-devops-service-connection-with-multiple-azure-resource-group/" target="_blank" rel="noreferrer noopener">this post</a> will help you. </p>



<h1 class="wp-block-heading">Create the YAML files needed</h1>



<p>We will be creating 3 YAML files as listed below. </p>



<ol class="wp-block-list"><li><a href="https://docs.microsoft.com/en-us/azure/devops/pipelines/process/templates?WT.mc_id=AZ-MVP-5001828&amp;view=azure-devops" target="_blank" rel="noreferrer noopener">A template file</a> with the all the tasks, so that we can reuse them for the environment specific pipelines</li><li>A pipeline for Test environment</li><li>A pipeline for the production environment</li></ol>



<h2 class="wp-block-heading">Template file</h2>



<p>Let&#8217;s configure all the tasks needed in our template file. We will have 2 stages in our template. You can <a href="https://sibeeshpassion.com/azure-multi-stage-pipeline-for-asp-net-core-and-azure-deploy-to-azure-app-service/" target="_blank" rel="noreferrer noopener">read this post</a> if you are not sure how to configure the stages in the pipeline. </p>



<ol class="wp-block-list"><li>Build stage, for performing the tasks below <ul><li>Install .Net Core SDK</li><li>.Net restore</li><li>.Net build</li><li>.Net publish</li><li>Publish to Azure DevOps artefacts</li></ul></li><li>Deploy stage, to deploy the artefacts generated to the Azure Web App Service. This will involves the taks below. <ul><li>Download the artefact</li><li>Deploy</li></ul></li></ol>



<p>Our final template file will look like this. </p>



<script src="https://gist.github.com/SibeeshVenu/4951d95a528d6bef87cc353eeb010548.js"></script>



<h2 class="wp-block-heading">Add pipeline for Test environment</h2>



<p>As we have a template available, we can use this to configure the pipeline for our test environment. All you have to do is to refer to this template and pass the required parameters. This is how our pipeline for our test environment can look like. </p>



<script src="https://gist.github.com/SibeeshVenu/6f6d8f7ef94f781e33b71ca031908f1b.js"></script>



<p>Here, the parameter azure subscription is the service connection name that you have created in your Azure DevOps project. Refer <a rel="noreferrer noopener" href="https://sibeeshpassion.com/azure-devops-service-connection-with-multiple-azure-resource-group/" target="_blank">to this</a> to know more.  The wwebAppName is the name of your Azure Web App Service. </p>



<h2 class="wp-block-heading">Add pipeline for Prod environment</h2>



<p>Let&#8217;s create a new pipeline for our Prod environment to see how easily we can reuse the template. </p>



<script src="https://gist.github.com/SibeeshVenu/1c9f4a5d53e696cbb5241efa0bef1ef3.js"></script>



<p>Wasn&#8217;t that cool?</p>



<h1 class="wp-block-heading">Configure the pipelines in the Azure DevOps</h1>



<p>Just creating the YAML field will not create the pipelines in our DevOps, as Microsoft has removed that option due to some security concerns. So we will have to configure them manually for the first time. Let&#8217;s do it. </p>



<ol class="wp-block-list"><li>Go to the Pipelines section from your Azure DevOps and click on the New pipeline button. </li><li>Select Azure Repos Git (YAML) from the next screen. </li><li>Select the repository that you pushed your YAML file code changes. </li><li>Azure DevOps will analyze your repository and sugges the YAML templates. Select the Existing Azure Pipeline YAML file option.</li><li>Selct the branch and the path to your YAML file as in the preceding image, review the same and run the pipeline. </li></ol>



<figure class="wp-block-image size-full"><a href="/wp-content/uploads/2021/12/image-8.png"><img decoding="async" width="801" height="376" src="/wp-content/uploads/2021/12/image-8.png" alt="" class="wp-image-14538" srcset="/wp-content/uploads/2021/12/image-8.png 801w, /wp-content/uploads/2021/12/image-8-300x141.png 300w, /wp-content/uploads/2021/12/image-8-768x361.png 768w" sizes="(max-width: 801px) 100vw, 801px" /></a><figcaption>Configure the pipelines in Azure DevOps</figcaption></figure>



<p>That&#8217;s it. Everything else will be working as expected from the next time as we have configured the triggers in the pipelines. If you are getting an error as &#8220;Task &#8220;NETSdkError&#8221; skipped, due to false condition; (&#8216;$(_TargetFrameworkVersionWithoutV)&#8217; &gt; &#8216;$(NETCoreAppMaximumVersion)&#8217;) was evaluated&#8221;, you will have to make sure that you are installing the correct version of the .Net Core SDK as mentioned in <a href="https://stackoverflow.com/a/70352273/5550507" target="_blank" rel="noreferrer noopener">this answer</a>.</p>



<h1 class="wp-block-heading">Source code</h1>



<p>You can get the complete source code from this <a href="https://github.com/SibeeshVenu/deploy-.net6-azure-web-app-yaml" target="_blank" rel="noreferrer noopener">GitHub repository</a>. Please feel free to fork/star. </p>



<h2 class="wp-block-heading">Conclusion</h2>



<p>Here in this post, we have learned the following things.</p>



<ol class="wp-block-list" id="block-d40e081d-b702-477c-8b2d-f217c2c2b5fb"><li>How to configure a YAML template</li><li>How to reuse a YAML template in the pipelines</li><li>How to deploy the .net 6 application to Azure Web App Service</li></ol>



<h2 class="wp-block-heading">About the Author</h2>



<p>I am yet another developer who is passionate about writing and video creation. I have written close to 500 blogs on my&nbsp;<a href="https://sibeeshpassion.com/" target="_blank" rel="noreferrer noopener">blog</a>. And I upload videos on my YouTube channels&nbsp;<a href="https://www.youtube.com/njanorumalayali" target="_blank" rel="noreferrer noopener">Njan Oru Malayali</a>&nbsp;and&nbsp;<a href="https://www.youtube.com/SibeeshPassion" target="_blank" rel="noreferrer noopener">Sibeesh Passion</a>. Please feel free to follow me.</p>



<ul class="wp-block-list"><li><a href="https://github.com/SibeeshVenu">GitHub</a></li><li><a href="https://medium.com/@sibeeshvenu">medium</a></li><li><a href="https://twitter.com/sibeeshvenu">Twitter</a></li></ul>



<h2 class="wp-block-heading">Your turn. What do you think?</h2>



<p>Thanks a lot for reading. Did I miss anything that you may think is needed in this article? Could you find this post useful? Kindly do not forget to share your feedback.</p>



<p>Kindest Regards</p>



<p>Sibeesh Venu</p>
]]></content:encoded>
					
					<wfw:commentRss>https://sibeeshpassion.com/deploy-net-6-app-to-azure-from-azure-devops-using-pipelines/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Integrate Azure App Insights in 1 Minute to .Net6 Application</title>
		<link>https://sibeeshpassion.com/integrate-azure-app-insights-in-1-minute-to-net6-application/</link>
					<comments>https://sibeeshpassion.com/integrate-azure-app-insights-in-1-minute-to-net6-application/#disqus_thread</comments>
		
		<dc:creator><![CDATA[SibeeshVenu]]></dc:creator>
		<pubDate>Wed, 15 Dec 2021 11:43:51 +0000</pubDate>
				<category><![CDATA[Azure]]></category>
		<category><![CDATA[.net 6]]></category>
		<category><![CDATA[azure app insights]]></category>
		<guid isPermaLink="false">https://sibeeshpassion.com/?p=14527</guid>

					<description><![CDATA[Integrating an existing Azure App Insights into your application is never been easier than this. Within a minute you can do this. I am using the .net6 app and visual studio 2022.]]></description>
										<content:encoded><![CDATA[
<p>Integrating an existing Azure App Insights into your application is never been easier than this. Within a minute you can do this. I am using the .net6 app and visual studio 2022. Here are the steps to do that. </p>



<p>Right-click on the project and click on the Connected Service </p>



<figure class="wp-block-image size-full"><a href="/wp-content/uploads/2021/12/image-1.png"><img decoding="async" width="800" height="806" src="/wp-content/uploads/2021/12/image-1.png" alt="" class="wp-image-14529" srcset="/wp-content/uploads/2021/12/image-1.png 800w, /wp-content/uploads/2021/12/image-1-298x300.png 298w, /wp-content/uploads/2021/12/image-1-150x150.png 150w, /wp-content/uploads/2021/12/image-1-768x774.png 768w" sizes="(max-width: 800px) 100vw, 800px" /></a><figcaption>Add connected service menu</figcaption></figure>



<p>Click on the + icon in the Service Dependencies and then select Azure Application Insights from the list </p>



<figure class="wp-block-image size-full"><a href="/wp-content/uploads/2021/12/image-2.png"><img decoding="async" width="800" height="561" src="/wp-content/uploads/2021/12/image-2.png" alt="" class="wp-image-14530" srcset="/wp-content/uploads/2021/12/image-2.png 800w, /wp-content/uploads/2021/12/image-2-300x210.png 300w, /wp-content/uploads/2021/12/image-2-768x539.png 768w" sizes="(max-width: 800px) 100vw, 800px" /></a><figcaption>Add dependency screen</figcaption></figure>



<p>Log in and select your subscription and the Azure Application Insight instance </p>



<figure class="wp-block-image size-full"><a href="/wp-content/uploads/2021/12/image-3.png"><img decoding="async" width="800" height="561" src="/wp-content/uploads/2021/12/image-3.png" alt="" class="wp-image-14531" srcset="/wp-content/uploads/2021/12/image-3.png 800w, /wp-content/uploads/2021/12/image-3-300x210.png 300w, /wp-content/uploads/2021/12/image-3-768x539.png 768w" sizes="(max-width: 800px) 100vw, 800px" /></a><figcaption>Select service dependency </figcaption></figure>



<p>Configure your connection string name and choose how you want to save your connections string locally. I would recommend saving it to a secret.json file. You can get more information about this <a rel="noreferrer noopener" href="https://sibeeshpassion.com/why-not-secure-your-keys-and-secrets-asp-net-core-with-azure-key-vault-integration/" target="_blank">here</a> under the Secret Storage for Development Environment section. </p>



<figure class="wp-block-image size-full"><a href="/wp-content/uploads/2021/12/image-4.png"><img decoding="async" width="800" height="561" src="/wp-content/uploads/2021/12/image-4.png" alt="" class="wp-image-14532" srcset="/wp-content/uploads/2021/12/image-4.png 800w, /wp-content/uploads/2021/12/image-4-300x210.png 300w, /wp-content/uploads/2021/12/image-4-768x539.png 768w" sizes="(max-width: 800px) 100vw, 800px" /></a><figcaption>Provide connection string</figcaption></figure>



<p>Click Finish on the summary screen.</p>



<figure class="wp-block-image size-full"><a href="/wp-content/uploads/2021/12/image-5.png"><img decoding="async" width="800" height="561" src="/wp-content/uploads/2021/12/image-5.png" alt="" class="wp-image-14533" srcset="/wp-content/uploads/2021/12/image-5.png 800w, /wp-content/uploads/2021/12/image-5-300x210.png 300w, /wp-content/uploads/2021/12/image-5-768x539.png 768w" sizes="(max-width: 800px) 100vw, 800px" /></a><figcaption>Summary of changes</figcaption></figure>



<p>You will be able to see the progress in the next screen.</p>



<figure class="wp-block-image size-full"><a href="/wp-content/uploads/2021/12/image-6.png"><img decoding="async" width="800" height="561" src="/wp-content/uploads/2021/12/image-6.png" alt="" class="wp-image-14534" srcset="/wp-content/uploads/2021/12/image-6.png 800w, /wp-content/uploads/2021/12/image-6-300x210.png 300w, /wp-content/uploads/2021/12/image-6-768x539.png 768w" sizes="(max-width: 800px) 100vw, 800px" /></a><figcaption>Dependency configuration progress</figcaption></figure>



<p>Click on the Git changes window, your changes should look like the image below. </p>



<figure class="wp-block-image size-full"><a href="/wp-content/uploads/2021/12/image-7.png"><img decoding="async" width="749" height="755" src="/wp-content/uploads/2021/12/image-7.png" alt="" class="wp-image-14535" srcset="/wp-content/uploads/2021/12/image-7.png 749w, /wp-content/uploads/2021/12/image-7-298x300.png 298w, /wp-content/uploads/2021/12/image-7-150x150.png 150w" sizes="(max-width: 749px) 100vw, 749px" /></a><figcaption>Git changes</figcaption></figure>



<p>Push your changes and deploy them to your web application.</p>



<h2 class="wp-block-heading">Conclusion</h2>



<p>Congratulations and thanks a lot for being with me this far. Here in this post, we learned how can we enable the Azure App Insights to our application. Happy Analysing!.</p>



<h2 class="wp-block-heading">About the Author</h2>



<p>I am yet another developer who is passionate about writing and video creation. I have written close to 500 blogs on my&nbsp;<a href="https://sibeeshpassion.com/" target="_blank" rel="noreferrer noopener">blog</a>. And I upload videos on my YouTube channels&nbsp;<a href="https://www.youtube.com/njanorumalayali" target="_blank" rel="noreferrer noopener">Njan Oru Malayali</a>&nbsp;and&nbsp;<a href="https://www.youtube.com/SibeeshPassion" target="_blank" rel="noreferrer noopener">Sibeesh Passion</a>. Please feel free to follow me.</p>



<ul class="wp-block-list"><li><a href="https://github.com/SibeeshVenu">GitHub</a></li><li><a href="https://medium.com/@sibeeshvenu">medium</a></li><li><a href="https://twitter.com/sibeeshvenu">Twitter</a></li></ul>



<h2 class="wp-block-heading">Your turn. What do you think?</h2>



<p>Thanks a lot for reading. Did I miss anything that you may think is needed in this article? Could you find this post useful? Kindly do not forget to share your feedback.</p>



<p>Kindest Regards</p>



<p>Sibeesh Venu</p>
]]></content:encoded>
					
					<wfw:commentRss>https://sibeeshpassion.com/integrate-azure-app-insights-in-1-minute-to-net6-application/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
	</channel>
</rss>
