<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Coder Legion - Recent posts tagged sudo</title>
<link>https://coderlegion.com/tag/sudo</link>
<description>Powered by Question2Answer</description>
<item>
<title>Deploy a Nanoc Static Site to S3 with GitHub Actions</title>
<link>https://coderlegion.com/14660/deploy-a-nanoc-static-site-to-s3-with-github-actions</link>
<description>
&lt;p&gt;&lt;img src=&quot;https://blog.ratnesh-maurya.com/images/blog/Easily-Deploy-Your-Nanoc-Website-to-S3-with-GitHub-Actions.jpg&quot; alt=&quot;Deploy a Nanoc Static Site to S3 with GitHub Actions&quot;&gt;&lt;/p&gt;&lt;p&gt;Deploying a static site to S3 manually means running &lt;code&gt;aws s3 sync&lt;/code&gt; from your laptop every time you make a change. That gets old fast. GitHub Actions can automate the entire flow: push to &lt;code&gt;main&lt;/code&gt;, and the site builds and deploys itself.&lt;/p&gt;
&lt;p&gt;This guide walks through the full setup for a &lt;a rel=&quot;nofollow&quot; href=&quot;https://nanoc.app/&quot;&gt;Nanoc&lt;/a&gt; site, but the S3 + GitHub Actions pattern works for any static site generator.&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/ratnesh-maurya/365-Days-of-DevOps/tree/main&quot;&gt;Source code on GitHub&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;what-you-need-before-starting&quot;&gt;What you need before starting&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;An &lt;strong&gt;AWS account&lt;/strong&gt; with an S3 bucket configured for static website hosting&lt;/li&gt;
&lt;li&gt;An &lt;strong&gt;IAM user&lt;/strong&gt; with scoped permissions (created in the steps below)&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;GitHub repository&lt;/strong&gt; containing your Nanoc source code&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;step-1-configure-the-s3-bucket-policy&quot;&gt;Step 1: Configure the S3 bucket policy&lt;/h2&gt;
&lt;p&gt;Your bucket needs a policy that allows public read access to its contents. Apply this to the bucket in the S3 console under Permissions &amp;gt; Bucket Policy:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-json&quot;&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;hljs-attr&quot;&gt;&quot;Version&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;2008-10-17&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;hljs-attr&quot;&gt;&quot;Id&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;PolicyForPublicWebsiteContent&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;hljs-attr&quot;&gt;&quot;Statement&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;hljs-punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;Sid&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;PublicReadGetObject&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;Effect&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;Allow&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;Principal&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;hljs-attr&quot;&gt;&quot;AWS&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;*&quot;&lt;/span&gt;
      &lt;span class=&quot;hljs-punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;Action&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;s3:GetObject&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;Resource&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;arn:aws:s3:::docsite-github-action/*&quot;&lt;/span&gt;
    &lt;span class=&quot;hljs-punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;hljs-punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;hljs-punctuation&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Replace &lt;code&gt;docsite-github-action&lt;/code&gt; with your actual bucket name.&lt;/p&gt;
&lt;h2 id=&quot;step-2-create-a-scoped-iam-user&quot;&gt;Step 2: Create a scoped IAM user&lt;/h2&gt;
&lt;p&gt;Create a dedicated IAM user for GitHub Actions &amp;mdash; don't use your root credentials. Attach this policy, which gives the minimum permissions needed for &lt;code&gt;s3 sync&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-json&quot;&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;hljs-attr&quot;&gt;&quot;Version&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;2012-10-17&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;hljs-attr&quot;&gt;&quot;Statement&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;hljs-punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;Sid&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;AccessToGetBucketLocation&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;Effect&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;Allow&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;Action&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;&quot;s3:GetBucketLocation&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;Resource&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;&quot;arn:aws:s3:::*&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;hljs-punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;hljs-punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;Sid&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;AccessToWebsiteBuckets&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;Effect&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;Allow&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;Action&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-punctuation&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;hljs-string&quot;&gt;&quot;s3:PutObject&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;hljs-string&quot;&gt;&quot;s3:PutObjectAcl&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;hljs-string&quot;&gt;&quot;s3:GetObject&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;hljs-string&quot;&gt;&quot;s3:ListBucket&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;hljs-string&quot;&gt;&quot;s3:DeleteObject&quot;&lt;/span&gt;
      &lt;span class=&quot;hljs-punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;Resource&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-punctuation&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;hljs-string&quot;&gt;&quot;arn:aws:s3:::docsite-github-action&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;hljs-string&quot;&gt;&quot;arn:aws:s3:::docsite-github-action/*&quot;&lt;/span&gt;
      &lt;span class=&quot;hljs-punctuation&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;hljs-punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;hljs-punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;hljs-punctuation&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;step-3-add-aws-credentials-to-github-secrets&quot;&gt;Step 3: Add AWS credentials to GitHub Secrets&lt;/h2&gt;
&lt;p&gt;In your GitHub repository, go to &lt;strong&gt;Settings &amp;gt; Secrets and variables &amp;gt; Actions&lt;/strong&gt; and add two repository secrets:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;AWS_ACCESS_KEY_ID&lt;/code&gt; &amp;mdash; your IAM user's access key&lt;/li&gt;
&lt;li&gt;&lt;code&gt;AWS_SECRET_ACCESS_KEY&lt;/code&gt; &amp;mdash; the corresponding secret key&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These are injected into the workflow at runtime. They never appear in logs.&lt;/p&gt;
&lt;h2 id=&quot;step-4-create-the-github-actions-workflow&quot;&gt;Step 4: Create the GitHub Actions workflow&lt;/h2&gt;
&lt;p&gt;Create &lt;code&gt;.github/workflows/deploy.yml&lt;/code&gt; in your repository:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-yaml&quot;&gt;&lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Nanoc&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Compile&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Upload&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;S3&lt;/span&gt;

&lt;span class=&quot;hljs-attr&quot;&gt;on:&lt;/span&gt;
  &lt;span class=&quot;hljs-attr&quot;&gt;push:&lt;/span&gt;
    &lt;span class=&quot;hljs-attr&quot;&gt;branches:&lt;/span&gt;
      &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;main&lt;/span&gt;

&lt;span class=&quot;hljs-attr&quot;&gt;jobs:&lt;/span&gt;
  &lt;span class=&quot;hljs-attr&quot;&gt;deploy:&lt;/span&gt;
    &lt;span class=&quot;hljs-attr&quot;&gt;runs-on:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ubuntu-latest&lt;/span&gt;

    &lt;span class=&quot;hljs-attr&quot;&gt;steps:&lt;/span&gt;
      &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Checkout&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Repository&lt;/span&gt;
        &lt;span class=&quot;hljs-attr&quot;&gt;uses:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;actions/checkout@v2&lt;/span&gt;

      &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Set&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;up&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Ruby&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Nanoc&lt;/span&gt;
        &lt;span class=&quot;hljs-attr&quot;&gt;run:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;|
          sudo apt-get update
          sudo apt-get install -y ruby-full build-essential zlib1g-dev
          sudo gem install bundler
          sudo gem install nanoc
          sudo gem install adsf
          sudo gem install kramdown
&lt;/span&gt;
      &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Build&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Nanoc&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Website&lt;/span&gt;
        &lt;span class=&quot;hljs-attr&quot;&gt;run:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;|
          ls
          cd tutorial &amp;amp;&amp;amp; nanoc
&lt;/span&gt;
      &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Set&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;AWS&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;credentials&lt;/span&gt;
        &lt;span class=&quot;hljs-attr&quot;&gt;uses:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;aws-actions/configure-aws-credentials@v1&lt;/span&gt;
        &lt;span class=&quot;hljs-attr&quot;&gt;with:&lt;/span&gt;
          &lt;span class=&quot;hljs-attr&quot;&gt;aws-access-key-id:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;${{&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;secrets.AWS_ACCESS_KEY_ID&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;}}&lt;/span&gt;
          &lt;span class=&quot;hljs-attr&quot;&gt;aws-secret-access-key:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;${{&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;secrets.AWS_SECRET_ACCESS_KEY&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;}}&lt;/span&gt;
          &lt;span class=&quot;hljs-attr&quot;&gt;aws-region:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ap-south-1&lt;/span&gt;

      &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Push&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;S3&lt;/span&gt;
        &lt;span class=&quot;hljs-attr&quot;&gt;run:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;aws&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;s3&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;sync&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;tutorial/output/&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;s3://docsite-github-action&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The workflow triggers on every push to &lt;code&gt;main&lt;/code&gt;. It installs Ruby and Nanoc, compiles the site, and syncs the output directory to your S3 bucket.&lt;/p&gt;
&lt;h2 id=&quot;alternatives-to-consider&quot;&gt;Alternatives to consider&lt;/h2&gt;
&lt;p&gt;This setup works well for simple static sites, but depending on your needs, other approaches might be a better fit:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Approach&lt;/th&gt;
&lt;th&gt;When to use it&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;S3 + CloudFront&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;You need HTTPS and a CDN for global performance&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Vercel / Netlify&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;You want zero-config deploys with preview URLs for every PR&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;GitHub Pages&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;You don't need AWS and want the simplest possible hosting&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AWS Amplify&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;You want managed CI/CD with automatic branch deploys on AWS&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;S3 alone doesn't give you HTTPS &amp;mdash; you'd need CloudFront in front of it for that. If HTTPS and preview deployments matter to you, Vercel or Netlify will save you time.&lt;/p&gt;
&lt;h2 id=&quot;common-pitfalls&quot;&gt;Common pitfalls&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Forgetting to enable static website hosting&lt;/strong&gt; on the S3 bucket &amp;mdash; without it, S3 serves files as downloads instead of web pages.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Overly broad IAM permissions&lt;/strong&gt; &amp;mdash; scope the policy to your specific bucket, not &lt;code&gt;s3:*&lt;/code&gt; on &lt;code&gt;*&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cache invalidation&lt;/strong&gt; &amp;mdash; &lt;code&gt;s3 sync&lt;/code&gt; updates files but doesn't invalidate CloudFront caches. If you add CloudFront later, add &lt;code&gt;aws cloudfront create-invalidation&lt;/code&gt; to the workflow.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Region mismatch&lt;/strong&gt; &amp;mdash; set &lt;code&gt;aws-region&lt;/code&gt; in the workflow to match your bucket's region.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The complete workflow YAML and policies are in the &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/ratnesh-maurya/365-Days-of-DevOps/tree/main&quot;&gt;repo&lt;/a&gt;.&lt;/p&gt;
</description>
<category>Other</category>
<guid isPermaLink="true">https://coderlegion.com/14660/deploy-a-nanoc-static-site-to-s3-with-github-actions</guid>
<pubDate>Mon, 13 Apr 2026 22:47:12 +0000</pubDate>
</item>
</channel>
</rss>