<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Ardd's Blog]]></title><description><![CDATA[I do DevOps :)]]></description><link>https://ardd.cloud</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1652106804282/uyRHhZ16V.png</url><title>Ardd&apos;s Blog</title><link>https://ardd.cloud</link></image><generator>RSS for Node</generator><lastBuildDate>Mon, 12 Oct 2026 14:45:52 GMT</lastBuildDate><atom:link href="https://ardd.cloud/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Visualizing AWS WAF Rules]]></title><description><![CDATA[If you’ve ever worked with AWS WAF rules, you know the struggle: creating rules directly via JSON works, but when you go back to the AWS console, you often get stuck with this dreaded message:

Cannot switch from JSON editor to visual editor.A rule t...]]></description><link>https://ardd.cloud/visualizing-aws-waf-rules</link><guid isPermaLink="true">https://ardd.cloud/visualizing-aws-waf-rules</guid><category><![CDATA[AWS]]></category><category><![CDATA[waf]]></category><category><![CDATA[visualization]]></category><category><![CDATA[aws-waf]]></category><dc:creator><![CDATA[Ardian]]></dc:creator><pubDate>Thu, 02 Oct 2025 22:37:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1759444557094/4bda7044-368e-4bb1-9286-6a48e03a3d35.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>If you’ve ever worked with <strong>AWS WAF rules</strong>, you know the struggle: creating rules directly via JSON works, but when you go back to the AWS console, you often get stuck with this dreaded message:</p>
<blockquote>
<p><strong>Cannot switch from JSON editor to visual editor.</strong><br /><em>A rule that contains nested statements or more than 5 statements is not supported. You must view the rule in the JSON viewer.</em></p>
</blockquote>
<p>That means once your rules get a little more complex, with nested <strong>AND/OR statements</strong> or more than five conditions, the visual editor in AWS just throws up its hands. You’re left staring at raw JSON, which isn’t exactly easy to parse at a glance.</p>
<hr />
<h2 id="heading-why-this-is-a-problem">Why This Is a Problem</h2>
<ul>
<li><p><strong>Hard to understand</strong>: Nested JSON statements can get messy very quickly.</p>
</li>
<li><p><strong>Hard to review</strong>: Security and DevOps teams often need a quick way to review rules before deploying.</p>
</li>
<li><p><strong>Hard to debug</strong>: If something doesn’t behave as expected, reading JSON doesn’t make troubleshooting easier.</p>
</li>
</ul>
<p>In short: AWS gives us <em>power</em>, but not <em>clarity</em>.</p>
<hr />
<h2 id="heading-enter-wafviz">Enter WAFViz</h2>
<p>That’s why I built <strong>WAFViz</strong>, a simple tool to visualize AWS WAF rules.</p>
<p>Instead of drowning in JSON, WAFViz turns your rules into a clear, <em>human-friendly</em> visualization. You can:</p>
<ul>
<li><p>Upload or paste your JSON rule.</p>
</li>
<li><p>See the hierarchy of <strong>AND/OR/NOT conditions</strong>.</p>
</li>
<li><p>Share visualizations with your team for reviews.</p>
</li>
</ul>
<p><em>No more guessing what a deeply nested JSON statement really means.</em></p>
<hr />
<h2 id="heading-example-before-and-after">Example: Before and After</h2>
<p><strong>Before</strong>: A wall of JSON that only the person who wrote it can decipher.</p>
<p><strong>After</strong>: Visualization where you can instantly see what conditions are combined and how.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1759445164120/b0e3f876-632c-4634-ab4e-3d45b6c02f1e.png" alt class="image--center mx-auto" /></p>
<p>This makes <strong>security reviews faster, collaboration easier, and debugging far less painful.</strong></p>
<hr />
<h2 id="heading-try-it-out">Try It Out</h2>
<p>You can check it out here 👉 <a target="_blank" href="https://wafviz.ardd.cloud/">https://wafviz.ardd.cloud</a></p>
<p>If you’re working with AWS WAF rules in JSON, this tool will <em>save you time and sanity.</em></p>
<hr />
<h2 id="heading-whats-next">What’s Next</h2>
<p>I’m planning to expand <strong>WAFViz</strong> with features like:</p>
<ul>
<li><p>Import directly from AWS.</p>
</li>
<li><p>Export visual diagrams as <strong>PNG/PDF</strong> for documentation.</p>
</li>
<li><p>Collaboration mode for teams.</p>
</li>
</ul>
<p>Feedback is super welcome… feel free to reach out and let me know how <strong>WAFViz</strong> can be more useful for you.</p>
]]></content:encoded></item><item><title><![CDATA[The Hidden Header: Next.js Next-Router-State-Tree and Why It Matters]]></title><description><![CDATA[When working with frameworks like Next.js, developers often expect that certain internal mechanisms remain invisible to the outside world. Unfortunately, that’s not always the case. Recently, while working on dele.to (an open-source project for shari...]]></description><link>https://ardd.cloud/the-hidden-header-nextjs-next-router-state-tree-and-why-it-matters</link><guid isPermaLink="true">https://ardd.cloud/the-hidden-header-nextjs-next-router-state-tree-and-why-it-matters</guid><category><![CDATA[Next.js]]></category><category><![CDATA[next-router-state-tree]]></category><dc:creator><![CDATA[Ardian]]></dc:creator><pubDate>Tue, 19 Aug 2025 21:18:34 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1755636924785/26d6ca03-9a7e-4b22-b65e-dbecd0647832.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>When working with frameworks like Next.js, developers often expect that certain internal mechanisms remain invisible to the outside world. Unfortunately, that’s not always the case. Recently, while working on <a target="_blank" href="https://dele.to">dele.to</a> (an open-source project for sharing sensitive data securely), a <a target="_blank" href="https://farcaster.xyz/cassie">security researcher</a> discovered that URL fragments where sent to the network request via header called <em>Next-Router-State-Tree</em>.</p>
<p>At first glance, it looks harmless, just part of Next.js’ internal routing logic. But under the hood, it can carry more than you would expect.</p>
<p><strong>What is Next-Router-State-Tree?</strong></p>
<p>Next.js uses the Next-Router-State-Tree header to pass routing state between server and client for navigation and hydration. In theory, it is meant for internal use only. In practice, it is leaked in network requests and visible in server logs, proxies, or observability tools.</p>
<p><strong>Why This Is a Problem</strong></p>
<ul>
<li><p><strong>URL Fragments and Query Data</strong><br />  The header may contain the full requested URL, including fragments (#hash) or sensitive query params. Normally, fragments never leave the browser, but here they get serialized into this header, meaning data you thought was client-only can unexpectedly travel across the wire.</p>
</li>
<li><p><strong>Logs and Monitoring</strong><br />  If your app is deployed behind a reverse proxy, CDN, or observability platform, this header is often logged. Suddenly, internal state, routing data, or sensitive identifiers become part of access logs you do not control.</p>
</li>
<li><p><strong>Attack Surface</strong><br />  Attackers could potentially harvest extra information from leaked headers if they gain access to logs or intercept requests. Even if the data is not outright sensitive, it adds unnecessary exposure.</p>
</li>
</ul>
<p><strong>Example from dele.to</strong></p>
<p>Here is an example link from dele.to:</p>
<p><code>https://dele.to/view/066d161a-5744-4904-8da3-bb7cbb3e07ba#wBPa77IW3/lKG/9dYGkke55cWGncciYqiKm8wJzYZMo=</code></p>
<p>next-router-state-tree looks like this:</p>
<p><code>%5B%22%22%2C%7B%22children%22%3A%5B%22view%22%2C%7B%22children%22%3A%5B%5B%22id%22%2C%221b0c4494-0899-4bb5-b6c9-66cdbbc23ad0%22%2C%22d%22%5D%2C%7B%22children%22%3A%5B%22__PAGE__%22%2C%7B%7D%2C%22%2Fview%2F1b0c4494-0899-4bb5-b6c9-66cdbbc23ad0%233ZHX%2F64lX9TrTx5KI1hgMrJzdgbwoRcHTQBxpcYbBQc%3D%22%2C%22refresh%22%5D%7D%5D%7D%5D%7D%2Cnull%2Cnull%2Ctrue%5D</code></p>
<p>which after decoding (included #fragment):</p>
<p><code>["",{"children":["view",{"children":[["id","1b0c4494-0899-4bb5-b6c9-66cdbbc23ad0","d"],{"children":["__PAGE__",{},"/view/1b0c4494-0899-4bb5-b6c9-66cdbbc23ad0#3ZHX/64lX9TrTx5KI1hgMrJzdgbwoRcHTQBxpcYbBQc=","refresh"]}]}]},null,null,true]</code></p>
<p>The secret after # is meant to remain in the browser only. But with Next-Router-State-Tree, that fragment ends up in the request header.</p>
<p>This means:</p>
<ul>
<li><p><strong><em>CDNs log it</em></strong></p>
</li>
<li><p><strong><em>Backends may store it</em></strong></p>
</li>
<li><p><strong><em>Debugging tools might capture it</em></strong></p>
</li>
</ul>
<p>In short, sensitive data can leak into places it was never meant to go.</p>
<p><strong>The Bigger Issue: No Official Fix</strong></p>
<p>Here is the tricky part: Next.js does not currently offer any way to disable the Next-Router-State-Tree header. It is baked into the framework.</p>
<p>The only option is to patch the package yourself, either by modifying Next.js internals or using a custom fork. For production apps that rely on fragments or handle sensitive routing, this is a serious limitation.</p>
<p>As part of addressing this in <em>dele.to</em>, we published a workaround patch in <a target="_blank" href="https://github.com/dele-to/dele-to/pull/7">PR #7</a>. This removes the header in self-hosted deployments until a proper framework-level fix exists.</p>
<p><a target="_blank" href="https://github.com/vercel/next.js/issues/82801">Issue</a> has been opened in Next.js for actual fix</p>
<p><strong>Mitigations Until Then</strong></p>
<ul>
<li><p>Do not rely on fragments for sensitive data such as tokens or IDs</p>
</li>
<li><p>Strip the header at your proxy or load balancer level (for example, drop it in Nginx or Cloudflare)</p>
</li>
<li><p>Audit your logs to make sure fragments are not being stored</p>
</li>
<li><p>Apply patches like <a target="_blank" href="https://github.com/dele-to/dele-to/pull/7">PR #7</a> to remove the header in self-hosted setups</p>
</li>
<li><p>Push for framework changes because this header should never serialize fragments in the first place</p>
</li>
</ul>
<p><strong>Closing Thoughts</strong></p>
<p>This issue was discovered in the course of building <a target="_blank" href="https://dele.to">dele.to</a>, but it is relevant to anyone using Next.js in production. It is a reminder that “internal” headers are not always internal once they leave the browser.</p>
<p>Frameworks that ship extra state in headers risk leaking information developers never intended to expose. Until Next.js provides a safe toggle, the only reliable option is to patch the package or strip the header manually.</p>
<p>If you are using Next.js, take a moment to inspect your traffic. You might be surprised what is riding along with your requests.</p>
<p>Thanks to <a target="_blank" href="https://farcaster.xyz/accountless.eth">accountless</a> and security researcher <a target="_blank" href="https://farcaster.xyz/cassie">Cassie Heart</a> @ <a target="_blank" href="https://quilibrium.com">Quilibrium.com</a> for finding this issue. Original discussion happened on <a target="_blank" href="https://farcaster.xyz/cassie/0xe77c9aab">Farcaster</a>.</p>
]]></content:encoded></item><item><title><![CDATA[Setup Cloudflare Pages Slack notifications]]></title><description><![CDATA[Hello there,
Today I am going to show you the how-to setup Cloudflare Pages deployment Slack notifications using GitHub Action
Let's touch base...  
What is Cloudflare Pages ?
Cloudflare Pages radically simplifies the process of developing and deploy...]]></description><link>https://ardd.cloud/setup-cloudflare-pages-slack-notifications</link><guid isPermaLink="true">https://ardd.cloud/setup-cloudflare-pages-slack-notifications</guid><category><![CDATA[cloudflare]]></category><category><![CDATA[github-actions]]></category><category><![CDATA[slack]]></category><dc:creator><![CDATA[Ardian]]></dc:creator><pubDate>Mon, 23 May 2022 12:07:15 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1652104972341/ol7VaSrP0.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hello there,
Today I am going to show you the how-to setup <strong>Cloudflare Pages</strong> deployment <strong>Slack notifications</strong> using <strong>GitHub Action</strong></p>
<p>Let's touch base...  </p>
<p><strong>What is Cloudflare Pages ?</strong></p>
<p>Cloudflare Pages radically simplifies the process of developing and deploying sites by taking care of all the tedious parts of web development. (<a target="_blank" href="https://blog.cloudflare.com/cloudflare-pages-ga/">read more</a>)</p>
<p><strong>Concept</strong></p>
<p>CF Pages as a concept is not new. 
For example, Github Pages is essentially exactly the same thing. There's additionally Netlify, CloudFront + S3, Vercel, and GitLab Pages. 
So you could ask yourself "<em>What's the point of using one more platform?</em>"</p>
<p>Let's list some reasons:</p>
<ul>
<li>In one dashboard you will find everything DNS management, Workers (Serverless functions in CF), WAF, Security Center, Page rules, and many more great things for your website!</li>
<li>Quick integration with GitHub and GitLab repos, fast builds, and awesome CDN!</li>
<li>Free plan is lit! (Unlimited sites, bandwidth, requests !!! yeah, you heard it right!)</li>
</ul>
<p><strong>Problem</strong></p>
<p>Assuming you already have set up CF Pages and just one thing of the puzzle is missing, <strong>Slack notifications</strong>!  </p>
<p>Currently, there is no direct integration for Slack notifications on CF Pages like other services such as Netlify and also there are some community posts like this one asking for solution https://community.cloudflare.com/t/get-slack-webhook-when-pages-build-finished-cloudflare-pages/311019 </p>
<p><strong>Solution</strong></p>
<p><em>Without further ado let's get our hands dirty !</em></p>
<p>There are plenty of blog posts on how to create CF Pages project so I will not include that in this post.</p>
<p>In order to achieve this I've published a <strong>Cloudflare Pages Slack Notification</strong> GitHub action </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1653306125906/BPm1tcEXz.png" alt="image.png" /></p>
<p>https://github.com/marketplace/actions/cloudflare-pages-slack-notification</p>
<p>Let's analyze it a bit how this action works:</p>
<ul>
<li>It is built on top of CF Pages Await by <a target="_blank" href="https://github.com/marketplace/actions/cloudflare-pages-await">WalshyDev</a></li>
<li>Uses <a target="_blank" href="https://www.npmjs.com/package/slack-notify">slack-notify</a> npm package</li>
</ul>
<p>Whenever there is a new push to GitHub it triggers GitHub action pipeline where it waits for deployment to finish by listening to Cloudflare API <a target="_blank" href="https://developers.cloudflare.com/pages/platform/api/">Read more</a></p>
<p>If the deployment fails it will show a Slack message like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1653302089500/Ef-1rWBIp.png" alt="image.png" /><em>(failed build notification)</em></p>
<p>If deployment is successful shows message as:
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1653302146017/pQTLXFsL-.png" alt="image.png" /><em>(deployment successful)</em></p>
<p>It also adds deployments directly in GitHub
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1653302256554/sWLFUfLeh.png" alt="image.png" /></p>
<p><strong>Usage</strong></p>
<p>Let's first add GitHub secrets: </p>
<ul>
<li><strong>CF_ACCOUNT_EMAIL</strong> - Cloudflare account email</li>
<li><strong>CF_API_KEY</strong> - Global API key (get it here https://dash.cloudflare.com/profile/api-tokens)</li>
<li><strong>CF_ACC_ID</strong> - Cloudflare account ID (from dashboard URL https://dash.cloudflare.com/180f4xxxxxxxxxx or go to Workers and on the right is  <code>Account ID</code>)</li>
<li><strong>CF_PROJECT</strong> - Cloudflare Pages project name (e.g test-dashboard)</li>
<li><strong>SLACK_WEBHOOK</strong> - <a target="_blank" href="https://slack.com/help/articles/115005265063-Incoming-webhooks-for-Slack">Slack Incoming Webhook</a> https://hooks.slack.com/....</li>
<li><strong>GITHUB_TOKEN</strong> - It will be automatically fetched by pipeline - no need to be added, this is used to add deployments on GH as per the screenshot above.</li>
</ul>
<p>Verify added secrets:
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1653302959341/bDYjmsgXZ.png" alt="image.png" /></p>
<p>Let's start creating GitHub action configuration yml.</p>
<p>Create a <code>.github/workflows/action.yml</code> file and add the following</p>
<pre><code>name: Send Slack notifications
on: 
  push
jobs:
  build:
    runs<span class="hljs-operator">-</span>on: ubuntu<span class="hljs-operator">-</span>latest
    steps:
    <span class="hljs-operator">-</span> uses: actions<span class="hljs-operator">/</span>checkout@v2
    <span class="hljs-operator">-</span> name: Send Slack deployment notifications
      uses: arddluma<span class="hljs-operator">/</span>cloudflare<span class="hljs-operator">-</span>pages<span class="hljs-operator">-</span>slack<span class="hljs-operator">-</span>notification@v2<span class="hljs-number">.2</span>
      with:
        accountEmail: ${{ secrets.CF_ACCOUNT_EMAIL  }}
        apiKey: ${{ secrets.CF_API_KEY  }}
        accountId: ${{ secrets.CF_ACC_ID  }}
        project: ${{ secrets.CF_PROJECT  }}
        githubToken: ${{ secrets.GITHUB_TOKEN }}
        slackWebHook: ${{ secrets.SLACK_WEBHOOK  }}
</code></pre><p>After running the pipeline you should get notifications on Slack like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1653306393592/es245cgI5.png" alt="image.png" /></p>
<p>And..... Voila 🎉</p>
<p>That's it! You now have deployment notifications on Slack! Enjoy :)</p>
<p>Thanks for reading!</p>
]]></content:encoded></item><item><title><![CDATA[Automate AWS IAM Key Rotation]]></title><description><![CDATA[Learn how to Automate AWS IAM Key Rotation
Introduction
We all know how difficult is to manage and rotate AWS IAM keys, there are a lot of tools out there that can help you manage your keys easly but in this blog post I will tell you about the proces...]]></description><link>https://ardd.cloud/automate-aws-iam-key-rotation</link><guid isPermaLink="true">https://ardd.cloud/automate-aws-iam-key-rotation</guid><category><![CDATA[AWS]]></category><category><![CDATA[Security]]></category><dc:creator><![CDATA[Ardian]]></dc:creator><pubDate>Tue, 20 Jul 2021 22:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1652103953527/5DS6iI0wY.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>Learn how to Automate AWS IAM Key Rotation</strong></p>
<p><strong>Introduction</strong></p>
<p>We all know how difficult is to manage and rotate AWS IAM keys, there are a lot of tools out there that can help you manage your keys easly but in this blog post I will tell you about the process and introduce you a new tool for key rotation.</p>
<p>Let's first touch base...</p>
<p><strong>What is IAM</strong></p>
<p>AWS <strong>Identity and Access Management (IAM)</strong> is a web service that helps you securely control access to AWS resources. You use IAM to control who is authenticated (signed in) and authorized (has permissions) to use resources.</p>
<p><strong>Key rotation</strong></p>
<p>Changing access keys (<strong>which consist of an access key ID and a secret access key</strong>) on a regular schedule is a well-known security best practice because it shortens the period an access key is active and therefore reduces the business impact if they are compromised.<a target="_blank" href="https://aws.amazon.com/blogs/security/how-to-rotate-access-keys-for-iam-users/">(reference)</a></p>
<p>To manually rotate keys AWS has documented steps needed to follow but this is a bit pain...</p>
<pre><code>To rotate access keys, you should follow these steps:

<span class="hljs-keyword">Create</span> a <span class="hljs-keyword">second</span> <span class="hljs-keyword">access</span> <span class="hljs-keyword">key</span> <span class="hljs-keyword">in</span> addition <span class="hljs-keyword">to</span> the one <span class="hljs-keyword">in</span> use.
<span class="hljs-keyword">Update</span> <span class="hljs-keyword">all</span> your applications <span class="hljs-keyword">to</span> <span class="hljs-keyword">use</span> the <span class="hljs-keyword">new</span> <span class="hljs-keyword">access</span> <span class="hljs-keyword">key</span> <span class="hljs-keyword">and</span> <span class="hljs-keyword">validate</span> that the applications <span class="hljs-keyword">are</span> working.
<span class="hljs-keyword">Change</span> the state <span class="hljs-keyword">of</span> the previous <span class="hljs-keyword">access</span> <span class="hljs-keyword">key</span> <span class="hljs-keyword">to</span> inactive.
<span class="hljs-keyword">Validate</span> that your applications <span class="hljs-keyword">are</span> still working <span class="hljs-keyword">as</span> expected.
<span class="hljs-keyword">Delete</span> the inactive <span class="hljs-keyword">access</span> key.
</code></pre><p>To get rid of all of this pain let me introduce you to the <code>aws-iam-key-rotation</code> tool that will help rotation your keys auto<code>magically</code></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1652103611461/k-C1PeL42.png" alt="image.png" /></p>
<p>Let's dig a bit deeper...</p>
<p><strong>How does it work?</strong></p>
<p>This script uses AWS CLI to rotate keys, in order to work you should add aws profile name and IAM user as parameter.</p>
<p><strong><em>Prerequisites</em></strong></p>
<ul>
<li>awscli (https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html)</li>
<li>jq (sudo apt-get install -y jq or brew install jq)</li>
</ul>
<p>Usage:</p>
<p><code>./aws-iam-key-rotation.sh aws-cli-profile iam-user-name</code></p>
<p>There are two cases covered by script</p>
<ol>
<li>If user has only one key configured</li>
<li>If user has two keys configured</li>
</ol>
<p>Screenshots:</p>
<p><em>If user has only 1 key configured</em></p>
<p>It will create new key - check if key works properly, set it up on existing aws cli profile and delete the old one.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1652103628441/V8tdiDnQ3.png" alt="image.png" /></p>
<p><em>If user has 2 keys configured</em></p>
<p>It will deactivate and delete the oldest key.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1652103651855/QZzbk36e2.png" alt="image.png" /></p>
<p><strong>Automating the process</strong></p>
<p>In this example I will be using crontab to schedule script to run every day at 00:00</p>
<ol>
<li>First run <code>crontab -e</code></li>
<li>At the beginning of the crontab file add this line <code>SHELL=/bin/bash</code></li>
<li><code>0 0 * * * /path/to/script/aws-iam-key-rotation.sh &lt;aws-cli-profile&gt; &lt;iam-user-name&gt;</code>
(if you want to see the logs of each triggered job you can add this <code>&gt;&gt; /path/to/log/file</code> at the end of command)
E.g <code>0 0 * * * /path/to/script/aws-iam-key-rotation.sh &lt;aws-cli-profile&gt; &lt;iam-user-name&gt; &gt;&gt; /path/to/log/file</code></li>
<li>Save it and wait for magic to happen :) </li>
</ol>
<p>Hope you enjoyed reading this blog post :)</p>
<p>Thank you !</p>
]]></content:encoded></item><item><title><![CDATA[Deploy React App to GitLab Pages]]></title><description><![CDATA[Learn how to deploy create-react-app to GitLab Pages
What is GitLab Pages
With GitLab Pages, you can publish static websites directly from a repository to GitLab for free. You can publish static files such as HTML, Jekyll, and CRA app. It’s the same ...]]></description><link>https://ardd.cloud/deploy-react-app-to-gitlab-pages</link><guid isPermaLink="true">https://ardd.cloud/deploy-react-app-to-gitlab-pages</guid><category><![CDATA[GitLab]]></category><category><![CDATA[Devops]]></category><category><![CDATA[ci-cd]]></category><dc:creator><![CDATA[Ardian]]></dc:creator><pubDate>Mon, 11 May 2020 22:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1652106859940/HJ-8TReE2.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>Learn how to deploy create-react-app to GitLab Pages</strong></p>
<p><strong>What is GitLab Pages</strong></p>
<p>With GitLab Pages, you can publish static websites directly from a repository to GitLab for free. You can publish static files such as HTML, Jekyll, and CRA app. It’s the same concept as GitHub Pages if you’ve tried it before.</p>
<p><strong>What is Create React App</strong></p>
<p>Create React App is a comfortable environment for learning React, and is the best way to start building a new single-page application in React.</p>
<p>Now… Let’s get our hands dirty …</p>
<p>The First step, we need to create a repository on GitLab. The Name of the repo should be like this: (username).gitlab.io</p>
<p>Your username should not include dots e.g ardd.cloud because of the HTTP protocol, when it’s deployed it will be sub-subdomain e.g ardd.cloud.github.io</p>
<p>Let’s create our repo first… </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1652102755226/dlVK2RRJD.png" alt="image.png" /></p>
<p>Now, we need to initiate our simple create single-page React app. Let’s start by installing npm install -g create-react-app or using yarn yarn global add create-react-app.</p>
<p>Run: npm init react-app my-app or yarn create react-app my-app</p>
<p>Go to <code>my-app</code> and run <code>npm start</code> or <code>yarn start</code> and it should look like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1652102776588/UfheHj1CF.png" alt="image.png" /></p>
<p>To edit you need to go to <code>src/App.js</code> file.</p>
<p>After editing we need to push changes to GitLab repo using those commands:</p>
<pre><code>git init
git remote add origin git@gitlab.com:username<span class="hljs-operator">/</span>username.gitlab.io.git
git add .
git commit <span class="hljs-operator">-</span>m <span class="hljs-string">"Initial commit"</span>
git push <span class="hljs-operator">-</span>u origin master
</code></pre><p>Now we need to edit Pages settings on repository settings. Go to the repo that you’ve created before, and then go to <code>Settings / General / Visibility</code>, project features, permissions click expand, and select <code>Everyone</code>on the dropdown list and hit Save changes.`</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1652102828065/4vGteYFYz.png" alt="image.png" /></p>
<p>To deploy we need to add <code>.gitlab-ci.yml</code>configuration, to do this we can add locally and then push through git but we can also add it from console. Go to <code>Project Overview</code> and click <code>Set up CI/CD</code> <code>.gitlab-ci.yml</code> should look like this:</p>
<p>image: node:10.16.1 #specify your node version</p>
<pre><code>pages:
  stage: deploy
  script:
  <span class="hljs-operator">-</span> yarn cache clean <span class="hljs-operator">-</span>f
  <span class="hljs-operator">-</span> yarn
  <span class="hljs-operator">-</span> unset CI
  <span class="hljs-operator">-</span> yarn run build
  <span class="hljs-operator">-</span> rm <span class="hljs-operator">-</span>rf <span class="hljs-keyword">public</span>
  <span class="hljs-operator">-</span> mv build <span class="hljs-keyword">public</span>
  artifacts:
    paths:
    <span class="hljs-operator">-</span> <span class="hljs-keyword">public</span>
  only:
  <span class="hljs-operator">-</span> master
</code></pre><p>You can get it on GitHub</p>
<p>Note: If you are running npm as a package manager then config should look like this:</p>
<pre><code><span class="hljs-attribute">image</span>: node:10.16.1 #specify your node version

<span class="solidity">pages:
  stage: deploy
  script:
  <span class="hljs-operator">-</span> npm cache clear <span class="hljs-operator">-</span><span class="hljs-operator">-</span>force
  <span class="hljs-operator">-</span> npm install
  <span class="hljs-operator">-</span> unset CI
  <span class="hljs-operator">-</span> npm run build
  <span class="hljs-operator">-</span> rm <span class="hljs-operator">-</span>rf <span class="hljs-keyword">public</span>
  <span class="hljs-operator">-</span> mv build <span class="hljs-keyword">public</span>
  artifacts:
    paths:
    <span class="hljs-operator">-</span> <span class="hljs-keyword">public</span>
  only:
  <span class="hljs-operator">-</span> master</span>
</code></pre><p>Commit changes and go to CI/CD / Pipelines you’ll see the pipeline running. Wait a bit and you will get <code>Job Succeded</code></p>
<p><img src="Uploading..." alt="image.png" /></p>
<p>**Yayyyy, you’ve deployed successfuly to GitLab Pages. To get your URL go to Settings / Pages.</p>
<p>View our page: ardd-cloud.gitlab.io</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1652102862825/KOv-v95Ym.png" alt="image.png" /></p>
<p>yayy</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1652102872033/6ZQrFr4Mg.png" alt="image.png" /></p>
<p>Thank you !</p>
]]></content:encoded></item></channel></rss>