<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Cybergavin</title>
    <description>The latest articles on DEV Community by Cybergavin (@cyber_gavin_038a51f0d5c30).</description>
    <link>https://dev.to/cyber_gavin_038a51f0d5c30</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2216778%2F6643f9cc-7c86-4ffc-9e10-40c2cbdd0f76.png</url>
      <title>DEV Community: Cybergavin</title>
      <link>https://dev.to/cyber_gavin_038a51f0d5c30</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/cyber_gavin_038a51f0d5c30"/>
    <language>en</language>
    <item>
      <title>Introducing s3-compliance: An OpenTofu Module for Secure and Standardized S3 Buckets</title>
      <dc:creator>Cybergavin</dc:creator>
      <pubDate>Sat, 18 Jan 2025 06:20:33 +0000</pubDate>
      <link>https://dev.to/cyber_gavin_038a51f0d5c30/introducing-s3-compliance-an-opentofu-module-for-secure-and-standardized-s3-buckets-5ccf</link>
      <guid>https://dev.to/cyber_gavin_038a51f0d5c30/introducing-s3-compliance-an-opentofu-module-for-secure-and-standardized-s3-buckets-5ccf</guid>
      <description>&lt;p&gt;In this blog post, I give you an overview of the &lt;code&gt;s3-compliance&lt;/code&gt; OpenTofu module, for provisioning and managing Amazon S3 buckets, while adhering to data classification standards.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is s3-compliance?
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;S3-compliance&lt;/code&gt; is an &lt;em&gt;opinionated&lt;/em&gt; &lt;strong&gt;OpenTofu module&lt;/strong&gt; designed to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create and manage one or more S3 buckets using a parameterized deployment.&lt;/li&gt;
&lt;li&gt;Embed organizational standards and policies into your infrastructure provisioning, based on data classifications.&lt;/li&gt;
&lt;li&gt;Provide flexibility for users to specify certain settings while enforcing pre-approved defaults.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Not all types of data require every S3 bucket feature such as versioning or object lock. The &lt;code&gt;s3-compliance&lt;/code&gt; module addresses these diverse needs by allowing different sets of configurations for different &lt;em&gt;data classifications&lt;/em&gt;. This tailored approach ensures that buckets are configured with only the necessary features for their specific data classification, striking a balance between &lt;em&gt;security&lt;/em&gt;, &lt;em&gt;efficiency&lt;/em&gt; and &lt;em&gt;cost&lt;/em&gt;. With this module, teams can focus on their work while ensuring their provisioned S3 buckets align with organization standards and recommended practices.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdtjc5kuci1z9a7gnd6ln.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdtjc5kuci1z9a7gnd6ln.png" alt="Image description" width="800" height="479"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Data Classifications
&lt;/h4&gt;

&lt;p&gt;The &lt;code&gt;s3-compliance&lt;/code&gt; module uses data classifications (e.g., public, internal, compliance) to determine which features to mandate. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Public Data:&lt;/strong&gt; Minimal security features, with public access intentionally enabled where appropriate.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Internal Data:&lt;/strong&gt; Encryption using KMS and logging are mandatory; versioning is optional.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Regulated Data:&lt;/strong&gt; Strict compliance requirements, including encryption, versioning, object lock, and logging.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By matching user-provided configurations to data classifications, the module allows flexibility for some settings, while enforcing others, thereby ensuring efficiency and compliance.&lt;/p&gt;

&lt;h4&gt;
  
  
  Compliance File
&lt;/h4&gt;

&lt;p&gt;The &lt;a href="https://github.com/cybergavin/terraform-aws-s3-compliance/blob/v1.0.0/s3-compliance.tf" rel="noopener noreferrer"&gt;&lt;code&gt;s3-compliance.tf&lt;/code&gt;&lt;/a&gt; file embedded in the module defines organizational standards for various data classifications, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Public access restrictions&lt;/li&gt;
&lt;li&gt;Encryption settings&lt;/li&gt;
&lt;li&gt;CloudTrail Logging&lt;/li&gt;
&lt;li&gt;Versioning&lt;/li&gt;
&lt;li&gt;Object locks for immutable storage&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Security teams vet this file to ensure compliance with organizational and regulatory requirements. A workflow may be triggered upon any changes to this compliance file to solicit the security team's approval. Alternatively, the security team may host this file in their own repository and make it available as a module output for consumption by the &lt;code&gt;s3-compliance&lt;/code&gt; module.&lt;/p&gt;

&lt;h4&gt;
  
  
  Input parameters
&lt;/h4&gt;

&lt;p&gt;Given below is the variable structure for the input parameters, showing that the &lt;code&gt;s3_buckets&lt;/code&gt; variable accepts a list of S3 buckets for provisioning. Most of the &lt;em&gt;optional&lt;/em&gt; configurations have defaults pre-defined as per the &lt;code&gt;s3-compliance&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"s3_buckets"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"List of S3 bucket configurations."&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="c1"&gt;# Basic configuration&lt;/span&gt;
    &lt;span class="nx"&gt;name&lt;/span&gt;                  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
    &lt;span class="nx"&gt;data_classification&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt; &lt;span class="c1"&gt;# Defaults are "public", "internal" and "compliance"&lt;/span&gt;
    &lt;span class="nx"&gt;public_access_enabled&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;optional&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;versioning_enabled&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;optional&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;logging_enabled&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;optional&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;tags&lt;/span&gt;                  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;optional&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt;

    &lt;span class="c1"&gt;# Encryption settings&lt;/span&gt;
    &lt;span class="nx"&gt;kms_master_key_id&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;optional&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# Use S3-managed keys by default&lt;/span&gt;
    &lt;span class="nx"&gt;compliance_standard&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;optional&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# e.g., "PCI-DSS", "HIPAA", "ISO27001"&lt;/span&gt;

    &lt;span class="c1"&gt;# Object Lock settings&lt;/span&gt;
    &lt;span class="nx"&gt;object_lock&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;optional&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="nx"&gt;mode&lt;/span&gt;           &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;optional&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# "GOVERNANCE" or "COMPLIANCE"&lt;/span&gt;
      &lt;span class="nx"&gt;retention_days&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;optional&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# Number of days to retain objects in locked state&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Lifecycle configuration&lt;/span&gt;
    &lt;span class="nx"&gt;lifecycle_transitions&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;optional&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="nx"&gt;intelligent_tiering_days&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;optional&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# Days for transitioning objects to the Intelligent Tiering class&lt;/span&gt;
      &lt;span class="nx"&gt;glacier_ir_days&lt;/span&gt;          &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;optional&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# Days for transitioning objects to the Glacier Instant Retrieval class&lt;/span&gt;
      &lt;span class="nx"&gt;glacier_fr_days&lt;/span&gt;          &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;optional&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# Days for transitioning objects to the Glacier Flexible Retrieval class&lt;/span&gt;
      &lt;span class="nx"&gt;glacier_da_days&lt;/span&gt;          &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;optional&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# Days for transitioning objects to the Glacier Deep Archive class&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nx"&gt;expiration_days&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;optional&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# Expiration after the latest transition&lt;/span&gt;
  &lt;span class="p"&gt;}))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Example Usage
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;s3-compliance&lt;/code&gt; module may be used as shown below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Provision S3 buckets for a sales application&lt;/span&gt;
&lt;span class="nx"&gt;module&lt;/span&gt; &lt;span class="s2"&gt;"sales-s3"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;source&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"git::https://github.com/cybergavin/terraform-aws-s3-compliance.git?ref=57e686755fd9c0c89b57ba1babe3f741ad6d6515
  org         = var.org
  app_id      = var.app_id
  environment = var.environment
  s3_buckets  = var.s3_buckets
  s3_logs     = var.s3_logs
  global_tags = var.global_tags
}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An example &lt;code&gt;s3_buckets&lt;/code&gt; variable for provisioning three S3 buckets for a sales application, is given below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;s3_buckets&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"catalogs"&lt;/span&gt;
        &lt;span class="nx"&gt;data_classification&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"public"&lt;/span&gt;
        &lt;span class="nx"&gt;public_access_enabled&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
        &lt;span class="nx"&gt;tags&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"description"&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Sales product catalogs"&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"inventory"&lt;/span&gt;
        &lt;span class="nx"&gt;data_classification&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"internal"&lt;/span&gt;
        &lt;span class="nx"&gt;tags&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"description"&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Sales inventory"&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;lifecycle_transitions&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;intelligent_tiering_days&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;180&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;expiration_days&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;365&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"payment"&lt;/span&gt;
        &lt;span class="nx"&gt;data_classification&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"compliance"&lt;/span&gt;
        &lt;span class="nx"&gt;compliance_standard&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"PCI-DSS"&lt;/span&gt;
        &lt;span class="nx"&gt;tags&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"description"&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Sales payment transactions"&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;object_lock&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;mode&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"COMPLIANCE"&lt;/span&gt;
            &lt;span class="nx"&gt;retention_days&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"2555"&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;lifecycle_transitions&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;intelligent_tiering_days&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;180&lt;/span&gt;
            &lt;span class="nx"&gt;glacier_ir_days&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;365&lt;/span&gt;
            &lt;span class="nx"&gt;glacier_fr_days&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;730&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;expiration_days&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2555&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a more detailed example of using the module refer the &lt;a href="https://github.com/cybergavin/terraform-aws-s3-compliance/tree/v1.0.0/examples/sales-s3" rel="noopener noreferrer"&gt;&lt;code&gt;sales-s3&lt;/code&gt; example&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Clone the module repository from GitHub: &lt;code&gt;git clone https://github.com/cybergavin/terraform-aws-s3-compliance.git&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Review the &lt;code&gt;s3-compliance.tf&lt;/code&gt; file with your security team and configure it to meet your data classification standards.&lt;/li&gt;
&lt;li&gt;Integrate the module into your OpenTofu project.&lt;/li&gt;
&lt;li&gt;Customize configurations where needed, while adhering to enforced defaults and use the module as per the example provided.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  CI/CD workflow for module build
&lt;/h2&gt;

&lt;p&gt;The module repository includes a GitHub Actions CI/CD workflow used for building the module that includes linting (&lt;code&gt;tofu fmt&lt;/code&gt; and &lt;code&gt;tflint&lt;/code&gt;), scanning (&lt;code&gt;checkov&lt;/code&gt;) , testing in a sandbox environment, creating a pre-release tag, creating a pull request and create a stable release tag. This built-in CI/CD workflow could be a good starting point for you to maintain the module, if required. Alternatively, you may integrate the module into your ecosystem (TACOS, Atlantis, Digger, HCP Cloud, etc.) and use the available features for a build and release workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;s3-compliance&lt;/code&gt; OpenTofu module bridges the gap between flexibility and security, allowing teams to provision S3 buckets that meet organizational standards easily. By embedding compliance directly into the provisioning process, this module simplifies operations, reduces risks, and accelerates infrastructure deployment.&lt;/p&gt;

&lt;p&gt;Check out the &lt;a href="https://github.com/cybergavin/terraform-aws-s3-compliance" rel="noopener noreferrer"&gt;&lt;code&gt;s3-compliance&lt;/code&gt;&lt;/a&gt; module on GitHub and get started today! Feel free to leave me feedback on this blog post and/or raise issues on GitHub.&lt;/p&gt;

</description>
      <category>opentofu</category>
      <category>terraform</category>
      <category>tutorial</category>
      <category>devto</category>
    </item>
    <item>
      <title>OpenTofu module for spoke VPC with TGW</title>
      <dc:creator>Cybergavin</dc:creator>
      <pubDate>Sun, 05 Jan 2025 06:46:44 +0000</pubDate>
      <link>https://dev.to/cyber_gavin_038a51f0d5c30/opentofu-module-for-spoke-vpc-with-tgw-4k6a</link>
      <guid>https://dev.to/cyber_gavin_038a51f0d5c30/opentofu-module-for-spoke-vpc-with-tgw-4k6a</guid>
      <description>&lt;p&gt;In this blog post, I’ll describe the &lt;code&gt;vpc-spoke-tgw&lt;/code&gt; OpenTofu module that simplifies the process of setting up networking for workload/spoke VPCs attached to a Transit Gateway (TGW). This module automates the creation of essential networking resources, including VPCs, subnets, route tables, security groups, DHCP option sets, and TGW attachments, facilitating integration with your organization’s hub-and-spoke architecture. This module also leverages the &lt;code&gt;terraform-null-label&lt;/code&gt; module to provide &lt;em&gt;consistent naming&lt;/em&gt; for provisioned resources.&lt;/p&gt;

&lt;p&gt;OpenTofu modules can be built and delivered as products, allowing other IT teams to use them independently.&lt;/p&gt;

&lt;h2&gt;
  
  
  An OpenTofu module for Hub-Spoke Deployments
&lt;/h2&gt;

&lt;p&gt;The image below represents a typical &lt;em&gt;hub-spoke&lt;/em&gt; architecture with the following:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hub&lt;/strong&gt;: An AWS account containing core infrastructure services (network ingress/egress, TGW, security appliances, shared services). &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Spoke&lt;/strong&gt;: An AWS account hosting a business application or workload with ingress/egress traffic from/to the Internet via the TGW&lt;/p&gt;

&lt;p&gt;The hub shares its TGW with the spoke via &lt;a href="https://aws.amazon.com/ram/" rel="noopener noreferrer"&gt;AWS Resource Access Manager (RAM)&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpk3vf92dt475ykh2x3e2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpk3vf92dt475ykh2x3e2.png" alt="AWS Hub-Spoke topology" width="800" height="454"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;vpc-spoke-tgw&lt;/code&gt; OpenTofu module accepts the TGW share invitation and sets up basic networking in the spoke (VPC, subnets, DHCP options, route tables with routes to the TGW, security groups).&lt;/p&gt;

&lt;h2&gt;
  
  
  Use Case: Setting Up Secure, Standardized Networking for a Multi-Account AWS Environment
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Scenario:
&lt;/h3&gt;

&lt;p&gt;Your organization has a multi-account AWS environment where the network team manages the central AWS account (hub), which includes the Transit Gateway (TGW), firewall configurations, and security measures like ingress/egress traffic management. The &lt;strong&gt;application&lt;/strong&gt; teams manage their own AWS accounts, where they deploy various workloads (e.g., web applications, APIs, etc.) and need secure connectivity to other services within the company’s AWS and on-premises networks as well as to the Internet. In some organizations, &lt;strong&gt;infrastructure&lt;/strong&gt; or &lt;strong&gt;platform&lt;/strong&gt; teams may set up workload AWS accounts before application teams deploy their workloads.&lt;/p&gt;

&lt;p&gt;To enable this, the application/infrastructure/platform teams attach their VPCs to the TGW shared by the network team. However, each team requires a &lt;strong&gt;standardized&lt;/strong&gt;, &lt;strong&gt;secure&lt;/strong&gt;, and &lt;strong&gt;automated&lt;/strong&gt; way to create their VPCs and configure networking components like subnets, route tables, security groups, and DHCP options.&lt;/p&gt;

&lt;h3&gt;
  
  
  Solution:
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;vpc-spoke-tgw&lt;/code&gt; OpenTofu module is designed to automate the networking setup in these &lt;strong&gt;workload VPCs&lt;/strong&gt; that need to connect to the shared TGW. The module streamlines and standardizes the process, ensuring consistent and secure networking for each team.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Features of the &lt;code&gt;vpc-spoke-tgw&lt;/code&gt; OpenTofu Module:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;VPC &amp;amp; Subnet Creation&lt;/strong&gt;: Creates a VPC with private subnets distributed across availability zones, when multiple subnets are configured.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TGW Attachment&lt;/strong&gt;: Accepts the TGW share and creates the attachment of the newly created VPC to the Transit Gateway managed by the network team, ensuring proper routing and connectivity.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Route Table Setup&lt;/strong&gt;: Creates route tables with routes to the TGW for secure communication between the application’s VPC and other VPCs or on-premises systems via the Transit Gateway.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security Groups&lt;/strong&gt;: Creates security groups to control inbound and outbound traffic based on application-specific needs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DHCP Option Set&lt;/strong&gt;: Creates a DHCP option set for proper domain name resolution across the VPC.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parameterized Deployment:&lt;/strong&gt; Can be used across multiple environments by using different input parameters or variables, specified in &lt;code&gt;.tfvars&lt;/code&gt; files, thereby facilitating reusability, consistency and automation (CI/CD pipelines).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Standardized Deployment:&lt;/strong&gt; Leverages the &lt;a href="https://github.com/cloudposse/terraform-null-label" rel="noopener noreferrer"&gt;&lt;code&gt;terraform-null-label&lt;/code&gt;&lt;/a&gt; module to provide consistent names for provisioned resources and allows for global tags, thereby facilitating adherence to naming and tagging standards.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Example Workflow:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Network Team&lt;/strong&gt;: Shares the TGW with application teams via AWS Resource Access Manager (RAM), sets the necessary security configurations and provides CIDR blocks (reserved in &lt;a href="https://www.infoblox.com/glossary/ipam-ip-address-management/" rel="noopener noreferrer"&gt;IPAM&lt;/a&gt;) for use by application teams for VPCs and subnets.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Application Teams&lt;/strong&gt;: Use the &lt;code&gt;vpc-spoke-tgw&lt;/code&gt; OpenTofu module to create their VPC and related networking resources (subnets, route table, security groups, etc.) with a simple configuration. The application teams can then deploy their applications into their networks an easily scale their networking (e.g., additional subnets, security groups) autonomously.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Benefits:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Consistency&lt;/strong&gt;: All application teams follow the same networking standards, simplifying management.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security&lt;/strong&gt;: By automatically setting up secure VPCs, subnets, and security groups, the module ensures that networking is configured in accordance with your organization's security policies.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Efficiency&lt;/strong&gt;: Application teams can focus on their workloads, while the OpenTofu module handles the repetitive networking setup tasks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalability&lt;/strong&gt;: As the company grows and more application teams are onboarded, the module allows for easy and automated scaling of networking infrastructure without additional manual effort.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How to access the &lt;code&gt;vpc-spoke-tgw&lt;/code&gt; OpenTofu module
&lt;/h3&gt;

&lt;p&gt;Access the module from my GitHub repo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/cybergavin/terraform-aws-vpc-spoke-tgw?tab=readme-ov-file" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;  - The module's repo contains GitHub Actions workflows for CI/CD pipelines used for module testing as well as an example on using the module.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;In this blog post, I demonstrated how you may use the &lt;code&gt;vpc-spoke-tgw&lt;/code&gt; OpenTofu module to streamline the setup of networking for application teams while ensuring consistency, security, and compliance with organization policies. Try it out and feel free to provide feedback either as a comment on this blog post or as an issue in the GitHub repo. This is an example of how Platform Engineering teams may deliver IaC products for easy and autonomous consumption by application teams. There are many ways to deliver IaC products. You may provide access to the module via a Git repo, a UI, use &lt;a href="https://itnext.io/spice-up-your-infrastructure-as-code-with-tacos-1a9c179e0783" rel="noopener noreferrer"&gt;TACOS&lt;/a&gt; software, etc., but you'll need to pick an approach that works well for your environment (infrastructure, policies, practices, culture).&lt;/p&gt;

</description>
      <category>programming</category>
      <category>tutorial</category>
      <category>devto</category>
    </item>
  </channel>
</rss>
