<?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: Frank Pimienta</title>
    <description>The latest articles on DEV Community by Frank Pimienta (@frankpimienta).</description>
    <link>https://dev.to/frankpimienta</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%2F910090%2Fd0df76d8-9afa-4860-953e-de4fd6af146c.jpg</url>
      <title>DEV Community: Frank Pimienta</title>
      <link>https://dev.to/frankpimienta</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/frankpimienta"/>
    <language>en</language>
    <item>
      <title>CloudFront VPC Origins: Integrating Private API Gateway</title>
      <dc:creator>Frank Pimienta</dc:creator>
      <pubDate>Sun, 06 Jul 2025 11:55:21 +0000</pubDate>
      <link>https://dev.to/frankpimienta/cloudfront-vpc-origins-integrating-private-api-gateway-18n3</link>
      <guid>https://dev.to/frankpimienta/cloudfront-vpc-origins-integrating-private-api-gateway-18n3</guid>
      <description>&lt;p&gt;On November 20, 2024, AWS announced VPC Origins. This new feature enables the use of CloudFront with applications hosted in private subnets, either through a load balancer (ALB or NLB) or EC2 instances.&lt;/p&gt;

&lt;p&gt;This excellent news was very well received, as user requests passing through CloudFront to AWS applications or services no longer needed to be exposed to the public internet. Additionally, it optimizes security management and facilitates the use of CloudFront as a single entry point for applications.&lt;/p&gt;

&lt;p&gt;While the primary use of VPC Origins is to establish private and secure communication with applications behind an ELB, such as ECS/EKS clusters or EC2 instances, &lt;strong&gt;we can leverage this new resource and go beyond the recommended usage&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Private API Gateway Integration&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;A key advantage of VPC Origins is establishing communication between CloudFront and a Private Endpoint of Amazon API Gateway &lt;strong&gt;REST&lt;/strong&gt; type. The most well-known options are between CloudFront and a Regional or Edge API Gateway Endpoint, but additional security elements need to be applied for it to work correctly.&lt;/p&gt;

&lt;p&gt;I have observed that the Edge API Gateway offers better global latencies (5-12ms), but the Private API Gateway with VPC Origins wins on security due to improved &lt;strong&gt;isolation&lt;/strong&gt;. However, this solution has a 7 times higher cost and significantly higher operational complexity (CF, ALB, VPC Endpoint, API Gateway). The decision depends on whether your use case requires critical enterprise systems or global public applications where latency is a top priority concern.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Recommended Use Cases&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Critical enterprise systems&lt;/strong&gt; where security is prioritized over latency.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Internal applications&lt;/strong&gt; that require complete isolation from the public network.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-account architectures&lt;/strong&gt; that require &lt;strong&gt;centralized access through CloudFront&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Technical Implementation Considerations&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Currently, the only way to establish this private communication is by adding the "x-apigw-api-id" header to the CloudFront origin configuration and using VPC Origins, an ALB, a VPC Endpoint, and the &lt;strong&gt;private Default Endpoint&lt;/strong&gt; of an API Gateway.&lt;/p&gt;

&lt;p&gt;But why can't I use the private Custom Domain Name that API Gateway provides? For two reasons: AWS doesn't allow us to modify the "Host" header in CloudFront's origin configuration, and VPC Origins doesn't support header rewriting with &lt;a href="mailto:Lambda@Edge"&gt;Lambda@Edge&lt;/a&gt;. To use the private Custom Domain Name, we need to send the "Host" header in the request. Due to the limitations of CloudFront and VPC Origins, we can only use the private Default Endpoint.&lt;/p&gt;

&lt;p&gt;There are some essential details I must mention for the implementation to work:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;We must use an ALB&lt;/strong&gt;. Why not an NLB? There are three main reasons. First, we must establish communication with the HTTPS protocol from the ALB to the VPC Endpoint. VPC Origins allows establishing HTTP communication to the ALB; however, we can't use this protocol because the ALB will attempt to maintain the same protocol and send the request to the Endpoint, resulting in a failed response. Second, when you configure VPC Origins with HTTPS, the load balancer requires a certificate. Currently, VPC Origins doesn't support an NLB with TLS, and in TCP passthrough, the NLB can't present one. However, we can configure the listener port number as desired; it doesn't have to be 443 (default for HTTPS). The third reason is that with an ALB, we can leverage forwarding rules to redirect to different target groups in case of more complex architectures.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The ALB must have a certificate signed by a trusted certificate authority&lt;/strong&gt;, such as GlobalSign, DigiCert, or Symantec. The reason we can't use a self-signed certificate is that CloudFront, when communicating via HTTPS with its origin, verifies that a trusted certificate authority has issued the certificate. If the origin (ALB) returns an expired, invalid, or self-signed certificate, CloudFront interrupts the TCP connection and returns HTTP status code 502.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The ALB must be created in the same account as the CloudFront&lt;/strong&gt; distribution. Currently, AWS doesn't allow creating the ALB in another account.&lt;/li&gt;
&lt;li&gt;The target group must be of the &lt;strong&gt;IP&lt;/strong&gt; type with the Health Check protocol set to &lt;strong&gt;HTTPS&lt;/strong&gt; and the Success codes set to &lt;strong&gt;403&lt;/strong&gt; when pointing to the root path (/).&lt;/li&gt;
&lt;li&gt;Security group configuration. When a VPC Origins is created for the first time, a security group called "&lt;strong&gt;CloudFront-VPCOrigins-Service-SG&lt;/strong&gt;" is created simultaneously. You must allow the security group created by VPC Origins to be included in the load balancer's security group.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Implemented Architectures&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Architecture 1:&lt;/strong&gt; Single-Account Deployment&lt;br&gt;
This basic architecture encompasses all components deployed within a single AWS account, making it ideal for simple use cases or development environments.&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%2Fvd5euduslcbfvmktlhzq.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%2Fvd5euduslcbfvmktlhzq.png" alt="Architecture 1" width="777" height="302"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Architecture 2:&lt;/strong&gt; Two or more Environments with Multi-Account Deployment&lt;br&gt;
In this configuration, we use one VPC Origins and one ALB to serve applications in two different environments, distributed across multiple AWS accounts. For this architecture to work and route traffic to various target groups, rules must be created in the ALB, using the "Host" header with the hostname of each CloudFront as the value.&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%2Fbj0hq5huebm6y6nhjb1y.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%2Fbj0hq5huebm6y6nhjb1y.png" alt="Architecture 2" width="800" height="301"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Architecture 3:&lt;/strong&gt; Multi-Application Architecture&lt;br&gt;
The most complex architecture includes multiple applications in two or more environments, with numerous CloudFronts, VPC Origins, ALBs, and across multiple AWS accounts. For this case, we must create some origins (one per application) and establish the corresponding behaviors that match each application/origin.&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%2Fyfqz1mwjooidxwg90qds.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%2Fyfqz1mwjooidxwg90qds.png" alt="Architecture 3" width="800" height="395"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Practical Implementation&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;This guide will walk you through the step-by-step process of implementing VPC Origins with a private API Gateway using the AWS console.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Verify base infrastructure&lt;/strong&gt;&lt;br&gt;
Objective: Validate that you have the necessary network infrastructure.&lt;br&gt;
Actions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Access the VPC console.&lt;/li&gt;
&lt;li&gt;Verify that you have at least two private subnets in different AZs. While it's technically possible to create the ALB in public subnets, to maintain completely private communication, &lt;strong&gt;it's recommended to deploy it in private subnets&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&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%2Fij8vk0n0v4ixyr5naaxv.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%2Fij8vk0n0v4ixyr5naaxv.png" alt="Subnets" width="800" height="253"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Create a VPC Endpoint for API Gateway&lt;/strong&gt;&lt;br&gt;
Objective: Establish private connectivity to the API Gateway.&lt;br&gt;
Actions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;strong&gt;VPC → Endpoints → Create Endpoint&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Configure the following parameters:&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Service category: AWS services&lt;/li&gt;
&lt;li&gt;Service name: com.amazonaws.[region].&lt;strong&gt;execute-api&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;VPC: Select your VPC&lt;/li&gt;
&lt;li&gt;Subnets: Select private subnets&lt;/li&gt;
&lt;li&gt;Security groups: Create a new one temporarily

&lt;ul&gt;
&lt;li&gt;Inbound: HTTPS (443) from the ALB's security group or subnets. If they're in different accounts, I recommend adding the CIDR blocks of the private subnets where the ALB is located. I don't recommend adding only IP addresses because they can change over time.&lt;/li&gt;
&lt;li&gt;Outbound: All traffic&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&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%2F5is7la3ins3eiiv7ew3t.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%2F5is7la3ins3eiiv7ew3t.png" alt="VPC Endpoint" width="800" height="302"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Create a private API Gateway&lt;/strong&gt;&lt;br&gt;
Objective: Configure the API Gateway that will receive requests.&lt;br&gt;
Actions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;strong&gt;API Gateway → Create API → REST API Private&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Configure:&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;API name: your-private-api&lt;/li&gt;
&lt;li&gt;Endpoint type: Private&lt;/li&gt;
&lt;li&gt;VPC endpoints: Select the VPC endpoint created in the previous step&lt;/li&gt;
&lt;li&gt;Configure Resource Policy&lt;/li&gt;
&lt;li&gt;Deploy to a stage (e.g., /dev)&lt;/li&gt;
&lt;li&gt;Enable logs (Errors and Info)&lt;/li&gt;
&lt;/ul&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%2F6znxlwgif4da8u0xwi22.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%2F6znxlwgif4da8u0xwi22.png" alt="Private API Gateway" width="800" height="257"&gt;&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%2F1agykwlxkvwwxddkz4ua.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%2F1agykwlxkvwwxddkz4ua.png" alt="Resource Policy" width="800" height="414"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Create Target Group&lt;/strong&gt;&lt;br&gt;
Objective: Configure the target group that will connect the ALB with the VPC Endpoint.&lt;br&gt;
Actions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;strong&gt;EC2 → Target Groups → Create target group&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Configure:&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Target type: IP addresses&lt;/li&gt;
&lt;li&gt;Protocol: HTTPS&lt;/li&gt;
&lt;li&gt;Port: 443&lt;/li&gt;
&lt;li&gt;VPC: Your VPC&lt;/li&gt;
&lt;li&gt;Health check protocol: HTTPS&lt;/li&gt;
&lt;li&gt;Health check path: /&lt;/li&gt;
&lt;li&gt;Success codes: 403&lt;/li&gt;
&lt;li&gt;In Register targets, add the VPC Endpoint IPs:

&lt;ul&gt;
&lt;li&gt;Go to VPC → Endpoints → [your-endpoint] → Network interfaces&lt;/li&gt;
&lt;li&gt;Copy the private IPs and add them as targets&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&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%2Fgrcoi4r1pnplc1eot1at.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%2Fgrcoi4r1pnplc1eot1at.png" alt="Target Group" width="800" height="291"&gt;&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%2Fuwj2m6fvhkgos2wd755c.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%2Fuwj2m6fvhkgos2wd755c.png" alt="Target Group" width="800" height="195"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5: Create Application Load Balancer&lt;/strong&gt;&lt;br&gt;
Objective: Configure the ALB that will act as a "proxy" to the VPC Endpoint.&lt;br&gt;
Actions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;strong&gt;EC2 → Load Balancers → Create load balancer → Application Load&lt;/strong&gt; Balancer.&lt;/li&gt;
&lt;li&gt;Basic configuration:&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Scheme: Internal&lt;/li&gt;
&lt;li&gt;IP address type: IPv4&lt;/li&gt;
&lt;li&gt;VPC: Your VPC&lt;/li&gt;
&lt;li&gt;Subnets: Select private subnets (minimum 2 AZs)&lt;/li&gt;
&lt;li&gt;Security groups: Create a new one:

&lt;ul&gt;
&lt;li&gt;Inbound: HTTPS (443). Temporarily add the CloudFront managed prefix list "com.amazonaws.global.cloudfront.origin-facing". This rule will be changed later once the VPC Origins is created.&lt;/li&gt;
&lt;li&gt;Outbound: All traffic&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Listener: HTTPS:443&lt;/li&gt;

&lt;li&gt;SSL certificate: Select your valid certificate&lt;/li&gt;

&lt;li&gt;Default action: Forward to target group (created in step 4)&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Validation: Wait for the ALB to be "Active" and the target group to be "Healthy".&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%2Fmcctj0hq64zi40gwla6q.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%2Fmcctj0hq64zi40gwla6q.png" alt="ALB" width="800" height="303"&gt;&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%2F4pru4dqvv4iusv0rc92g.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%2F4pru4dqvv4iusv0rc92g.png" alt="ALB" width="800" height="330"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 6: Create VPC Origin&lt;/strong&gt;&lt;br&gt;
Objective: Establish the connection between CloudFront and your VPC.&lt;br&gt;
Actions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;strong&gt;CloudFront → VPC origins → Create VPC origin&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Configure:&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Origin domain: ARN of the ALB created in the previous step&lt;/li&gt;
&lt;li&gt;Protocol: HTTPS only&lt;/li&gt;
&lt;li&gt;Port: 443&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Validation: The VPC Origin should display a "Deployed" status within 5–10 minutes.&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%2Fo0ovo677y2t9k1ajx61z.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%2Fo0ovo677y2t9k1ajx61z.png" alt="VPC Origins" width="800" height="402"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 7: Update ALB's Security Groups&lt;/strong&gt;&lt;br&gt;
Objective: Allow communication between CloudFront and the ALB.&lt;br&gt;
Actions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;strong&gt;EC2 → Security Groups&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Edit the ALB's security group:&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Inbound rules: Modify the previously created rule and add the source "CloudFront-VPCOrigins-Service-SG"&lt;/li&gt;
&lt;/ul&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%2Fay1ogctn9x5qhbf5byus.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%2Fay1ogctn9x5qhbf5byus.png" alt="Security Group" width="800" height="204"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 8: Create CloudFront distribution&lt;/strong&gt;&lt;br&gt;
Objective: Configure CloudFront to use the VPC Origin.&lt;br&gt;
Actions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;strong&gt;CloudFront → Create distribution&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Origin settings:&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Origin domain: Select your VPC origin&lt;/li&gt;
&lt;li&gt;Protocol: HTTPS only&lt;/li&gt;
&lt;li&gt;Custom headers: Add&lt;/li&gt;
&lt;li&gt;Header name: &lt;strong&gt;"x-apigw-api-id"&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Value: &lt;strong&gt;[API-ID from step 3]&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Origin path: /dev (or your stage)&lt;/li&gt;
&lt;li&gt;Default cache behavior:

&lt;ul&gt;
&lt;li&gt;Viewer protocol policy: HTTPS only&lt;/li&gt;
&lt;li&gt;Cache policy: Managed-CachingDisabled (for testing)&lt;/li&gt;
&lt;li&gt;Origin request policy: If you're going to implement Architecture 2, add the Managed-AllViewer policy so you can capture the hostname in ALB rules.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Settings:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Alternate domain name (CNAME): your-domain.com (optional)&lt;/li&gt;
&lt;li&gt;SSL certificate: Use ACM certificate if you have a CNAME&lt;/li&gt;
&lt;/ul&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%2Fhri9iibgovorq5ksqn3m.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%2Fhri9iibgovorq5ksqn3m.png" alt="Cloud Front - Origins" width="800" height="187"&gt;&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%2F2h8gftjiplvuea7aqnak.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%2F2h8gftjiplvuea7aqnak.png" alt="Cloud Front - Add custom header" width="800" height="294"&gt;&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%2F536eo7347ttem2qbjf1x.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%2F536eo7347ttem2qbjf1x.png" alt="Cloud Front - Bahaviors" width="800" height="187"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 9: Testing and validation&lt;/strong&gt;&lt;br&gt;
Objective: Verify that the entire integration works correctly.&lt;br&gt;
Basic connectivity test:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;curl -v https://[cloudfront-domain]/[your-resource]&lt;/li&gt;
&lt;li&gt;Expected result:

&lt;ul&gt;
&lt;li&gt;Response data from your API&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;"x-amz-apigw-id"&lt;/strong&gt; header in the response&lt;/li&gt;
&lt;li&gt;No 502 or 503 errors&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&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%2F13eed4bwsihstjiopipi.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%2F13eed4bwsihstjiopipi.png" alt="Curl Test" width="663" height="646"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Verify API Gateway logs:

&lt;ul&gt;
&lt;li&gt;Go to &lt;strong&gt;CloudWatch → Log groups → API-Gateway-Execution-Logs_[api-gateway-ID]/[stage]&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Look for the &lt;strong&gt;"x-apigw-api-id"&lt;/strong&gt; header in the logs&lt;/li&gt;
&lt;li&gt;Confirm that requests are coming from CloudFront&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&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%2Fxsarziejeko7w675mdd5.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%2Fxsarziejeko7w675mdd5.png" alt="Logs" width="800" height="448"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I hope this article is of great help to you. Best regards, and I look forward to seeing you next time. Thank you!&lt;/p&gt;

</description>
      <category>cloudfront</category>
      <category>vpcorigins</category>
      <category>apigateway</category>
    </item>
    <item>
      <title>CI/CD + AWS CloudFormation + Multi-Account</title>
      <dc:creator>Frank Pimienta</dc:creator>
      <pubDate>Sat, 17 Sep 2022 19:09:16 +0000</pubDate>
      <link>https://dev.to/frankpimienta/cicd-aws-cloudformation-multi-account-4ih1</link>
      <guid>https://dev.to/frankpimienta/cicd-aws-cloudformation-multi-account-4ih1</guid>
      <description>&lt;p&gt;I want to share a practical example of how you can deploy and update your infrastructure on AWS with a &lt;strong&gt;CI/CD pipeline&lt;/strong&gt;, &lt;strong&gt;AWS CloudFormation&lt;/strong&gt;, and from a &lt;strong&gt;root account to multiple accounts&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If your organization has several AWS accounts, I recommend that the deployment and updating of the infrastructure be done from an account that it delegates and belongs to the organization or from its central account (Root) to the other accounts that they have according to its purpose (production, development, test, etc.) In addition, I recommend using native AWS services such as CodeCommit (private Git repository), CodeBuild (continuous integration service), CodePipeline (continuous delivery service), and CloudFormation (Infrastructure as Code).&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%2Fk1m603s2mfuj3qr3c24p.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%2Fk1m603s2mfuj3qr3c24p.png" alt="Figure 1: CI/CD pipeline" width="800" height="393"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pipeline Description:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;AWS CloudFormation templates should be stored in a Git repository on CodeCommit, to perform workflows that include code revisions and modifications, pull requests, and merge branches.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The CodePipeline service should be used for the CI/CD pipeline and to automate the environment deployment process.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The templates will be uploaded to a bucket in S3 so they can be accessed by the CloudFormation stacks in the destination accounts.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;AWS CloudFormation (Stack Set) service will be used in the central account ID:111111111111 to provision and manage the resources in the target accounts: dev-ID:222222222222, prod-ID:333333333333&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CodeBuild service must be used to perform a test and thus be able to check the availability of the deployed environment.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;&lt;strong&gt;AWS CloudFormation templates:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I make available some AWS CloudFormation templates that I created for this DEMO. You can get them from the following repository on GitHub:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/frankpimienta/DEMO-CICD" rel="noopener noreferrer"&gt;https://github.com/frankpimienta/DEMO-CICD&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There is a root template called &lt;strong&gt;kloudpepper-ROOT.yml&lt;/strong&gt;, which is used to define the parameters that will be inserted in the infrastructure to be deployed, and in turn, calls the other separate templates by types of resources or services. The templates are made this way to have an organization when modifying values or data in that particular resource. I explain it better in the previous article:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/frankpimienta/aws-cloudformation-nested-stacks-9k5"&gt;https://dev.to/frankpimienta/aws-cloudformation-nested-stacks-9k5&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also, you're going to look at a JSON file called &lt;strong&gt;parameters-test.json&lt;/strong&gt;. This file contains the parameters that will be used in the environment to be deployed. For example, the CIDR of the VPC, the name of the environment, if it is a production or non-production environment type, and others. We will carry out the DEMO simulating a non-productive environment.&lt;/p&gt;

&lt;p&gt;And finally, the &lt;strong&gt;buildspec.yml&lt;/strong&gt; file, which we will use to define a set of build commands in CodeBuild and check that the environment was deployed correctly.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;CI/CD Configuration&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;1.In the delegate or Root account that will be use to configure CI/CD pipeline, must be created S3 bucket to deposit the templates that will be called later from the CloudFormation stacks of each destination account. To better understand, you can go back to Figure 1 and look at the pipeline. To create the repository, they must put the same name they defined for the environment. This step is essential since, in the templates, there is a parameter that refers to this name. Therefore, they can't put different names on the templates' parameters and in the bucket.&lt;/p&gt;

&lt;p&gt;Example:&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%2Fxf2xppxhqlrjcp7oyp6s.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%2Fxf2xppxhqlrjcp7oyp6s.png" alt="Image description" width="800" height="85"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;2.Insert the following policy in the bucket created. Have to change the IDs 111111111111 and 222222222222 with the correct IDs that they have in their accounts:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;{&lt;br&gt;
    "Version": "2012-10-17",&lt;br&gt;
    "Id": "Policy1644732224428",&lt;br&gt;
    "Statement": [&lt;br&gt;
        {&lt;br&gt;
            "Sid": "Stmt1644732214596",&lt;br&gt;
            "Effect": "Allow",&lt;br&gt;
            "Principal": {&lt;br&gt;
                "AWS": [&lt;br&gt;
                    "arn:aws:iam::111111111111:root",&lt;br&gt;
                    "arn:aws:iam::222222222222:root"&lt;br&gt;
                ]&lt;br&gt;
            },&lt;br&gt;
            "Action": "s3:GetObject",&lt;br&gt;
            "Resource": "arn:aws:s3:::kloudpepper-test/*"&lt;br&gt;
        }&lt;br&gt;
    ]&lt;br&gt;
}&lt;/code&gt;&lt;/p&gt;




&lt;p&gt;3.It's necessary to create two (2) roles to delegate the administration permissions of the destination accounts to the account where the CI/CD pipeline will be configured (&lt;strong&gt;Cross-Account IAM Role&lt;/strong&gt;) AWS has created two (2) AWS CloudFormation templates to create the roles and permissions in the accounts. I share the templates in the Git repository. So if you know to do the manual configuration, you can do it without problems. There is a lot of documentation that talks about it.&lt;/p&gt;

&lt;p&gt;3.1.In the delegate or main (Root) account, you can execute the following template in AWS CloudFormation:&lt;br&gt;
&lt;a href="https://github.com/frankpimienta/DEMO-CICD/blob/main/AWSCloudFormationStackSetAdministrationRole.yml" rel="noopener noreferrer"&gt;AWSCloudFormationStackSetAdministrationRole.yml&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You don't have to insert parameters.&lt;/p&gt;

&lt;p&gt;3.2.On the target accounts, execute the following template in AWS CloudFormation:&lt;br&gt;
&lt;a href="https://github.com/frankpimienta/DEMO-CICD/blob/main/AWSCloudFormationStackSetExecutionRole.yml" rel="noopener noreferrer"&gt;AWSCloudFormationStackSetExecutionRole.yml&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When you execute this template in AWS CloudFormation, it will insert the ID of the parent or delegate account (Root).&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%2F5vaqolrh7avtoujpsvjg.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%2F5vaqolrh7avtoujpsvjg.png" alt="Image description" width="800" height="242"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;4.Create a &lt;strong&gt;CodeCommit&lt;/strong&gt; repository:&lt;br&gt;
I like configuring the repository with approval rules and branches to make pull requests and control the modification of the templates. However, we won't be making those settings for this demo. Create the repository in CodeCommit and upload the templates found on GitHub: &lt;a href="https://github.com/frankpimienta/DEMO-CICD" rel="noopener noreferrer"&gt;https://github.com/frankpimienta/DEMO-CICD&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%2Ff0xqrl8209uf1rpt5lsk.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%2Ff0xqrl8209uf1rpt5lsk.png" alt="Image description" width="800" height="139"&gt;&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%2Ff5p7jrjzc49deskzyhfu.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%2Ff5p7jrjzc49deskzyhfu.png" alt="Image description" width="800" height="454"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;5.Create a building project in &lt;strong&gt;CodeBuild&lt;/strong&gt;. Add the following parameters:&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%2F31a6kdgazzvss1dpub53.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%2F31a6kdgazzvss1dpub53.png" alt="Image description" width="800" height="654"&gt;&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%2Ffwxifg014zgli6d2f956.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%2Ffwxifg014zgli6d2f956.png" alt="Image description" width="800" height="603"&gt;&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%2Fb976qazxb9etscvy2hqf.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%2Fb976qazxb9etscvy2hqf.png" alt="Image description" width="800" height="640"&gt;&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%2Fxndyq2e5sfe3ltxtb0hi.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%2Fxndyq2e5sfe3ltxtb0hi.png" alt="Image description" width="800" height="690"&gt;&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%2F9pyrqhh66blfmifn5a69.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%2F9pyrqhh66blfmifn5a69.png" alt="Image description" width="800" height="341"&gt;&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%2Fc982dwny2c9waty89r4d.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%2Fc982dwny2c9waty89r4d.png" alt="Image description" width="800" height="279"&gt;&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%2Fpewtmlb2xcnexvvwxqzt.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%2Fpewtmlb2xcnexvvwxqzt.png" alt="Image description" width="800" height="248"&gt;&lt;/a&gt;&lt;br&gt;
Once the project is created, it should look like this:&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%2Fsm3gssdciqt8ggqwtdwc.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%2Fsm3gssdciqt8ggqwtdwc.png" alt="Image description" width="800" height="140"&gt;&lt;/a&gt;&lt;br&gt;
5.1.When you finish creating the project, a role is automatically created for its execution. It's necessary to enter the project and search for this role. A policy must then be inserted to assume the role of the target account. Follow the next steps:&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%2F1wi8cj2dcpl29uejh6r4.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%2F1wi8cj2dcpl29uejh6r4.png" alt="Image description" width="577" height="525"&gt;&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%2Fvqj0m1513e3xmv0xrnb8.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%2Fvqj0m1513e3xmv0xrnb8.png" alt="Image description" width="438" height="367"&gt;&lt;/a&gt;&lt;br&gt;
5.2.Insert the following policy inside the role. Enter the valid ID of the destination account:&lt;br&gt;
&lt;code&gt;{&lt;br&gt;
    "Version": "2012-10-17",&lt;br&gt;
    "Statement": [&lt;br&gt;
        {&lt;br&gt;
            "Effect": "Allow",&lt;br&gt;
            "Resource": [&lt;br&gt;
                "arn:aws:iam::222222222222:role/AWSCloudFormationStackSetExecutionRole"&lt;br&gt;
            ],&lt;br&gt;
            "Action": [&lt;br&gt;
                "sts:AssumeRole"&lt;br&gt;
            ]&lt;br&gt;
        }&lt;br&gt;
    ]&lt;br&gt;
}&lt;/code&gt;&lt;/p&gt;




&lt;p&gt;6.Create a pipeline in &lt;strong&gt;CodePipeline&lt;/strong&gt;. Enter the following parameters:&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%2Fbcpt52jut96dlz0t16mi.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%2Fbcpt52jut96dlz0t16mi.png" alt="Image description" width="694" height="416"&gt;&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%2Fr6a4cdoome2aquklbgn5.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%2Fr6a4cdoome2aquklbgn5.png" alt="Image description" width="671" height="530"&gt;&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%2Fu3enm1r2gbty2l2c2jep.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%2Fu3enm1r2gbty2l2c2jep.png" alt="Image description" width="800" height="335"&gt;&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%2Fozx5z9shu9iz7xl9trs5.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%2Fozx5z9shu9iz7xl9trs5.png" alt="Image description" width="800" height="693"&gt;&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%2Fx7ba7xhzu5enww7nc63g.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%2Fx7ba7xhzu5enww7nc63g.png" alt="Image description" width="800" height="734"&gt;&lt;/a&gt;&lt;br&gt;
6.1.Once you finish configuring and saving the creation of the pipeline, it will automatically start its execution. Next, stop execution so you can continue configuring the pipeline:&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%2Finzmrcwxwq79f2dishih.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%2Finzmrcwxwq79f2dishih.png" alt="Image description" width="800" height="201"&gt;&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%2Fd0nvt773dyjw5v78z4tn.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%2Fd0nvt773dyjw5v78z4tn.png" alt="Image description" width="766" height="754"&gt;&lt;/a&gt;&lt;br&gt;
6.2.Edit the pipeline:&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%2Fpkwzkdldxjdwj1n87l1w.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%2Fpkwzkdldxjdwj1n87l1w.png" alt="Image description" width="800" height="302"&gt;&lt;/a&gt;&lt;br&gt;
6.3.After the Source stage, add a new stage and enter a name:&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%2Fp9siafd8jtr2ifh4ch6t.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%2Fp9siafd8jtr2ifh4ch6t.png" alt="Image description" width="800" height="331"&gt;&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%2F6ffvzroehvj2uanghf1y.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%2F6ffvzroehvj2uanghf1y.png" alt="Image description" width="726" height="276"&gt;&lt;/a&gt;&lt;br&gt;
6.4.Add an action in the Upload_S3 stage:&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%2F67aecshboykk29iqp2kc.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%2F67aecshboykk29iqp2kc.png" alt="Image description" width="800" height="329"&gt;&lt;/a&gt;&lt;br&gt;
6.5.Add the following parameters in the Upload_S3 action:&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%2Fj9g987b2sdjs738fytog.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%2Fj9g987b2sdjs738fytog.png" alt="Image description" width="800" height="1162"&gt;&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%2Fybrkk4m1vs63pf7121ri.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%2Fybrkk4m1vs63pf7121ri.png" alt="Image description" width="800" height="699"&gt;&lt;/a&gt;&lt;br&gt;
6.6.Once you save the configuration in the Upload_S3 action, you have to save the stage:&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%2Fo4b6m6r9zgpyljcldr21.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%2Fo4b6m6r9zgpyljcldr21.png" alt="Image description" width="800" height="158"&gt;&lt;/a&gt;&lt;br&gt;
6.7.After the Deploy stage, add a new stage and enter a name:&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%2F4zmwwq4nvx9lovingn5q.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%2F4zmwwq4nvx9lovingn5q.png" alt="Image description" width="800" height="271"&gt;&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%2Fv4fqyljzilo37plnf5ut.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%2Fv4fqyljzilo37plnf5ut.png" alt="Image description" width="717" height="277"&gt;&lt;/a&gt;&lt;br&gt;
6.8.Add an action in the Test stage:&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%2F6tti8j391cg1t4wvan3r.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%2F6tti8j391cg1t4wvan3r.png" alt="Image description" width="756" height="317"&gt;&lt;/a&gt;&lt;br&gt;
6.9.Enter the following parameters in the Test action:&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%2F41f1w3y5sixnen2chopt.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%2F41f1w3y5sixnen2chopt.png" alt="Image description" width="492" height="1027"&gt;&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%2Fln26akpl9e05tvtfqhs5.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%2Fln26akpl9e05tvtfqhs5.png" alt="Image description" width="800" height="565"&gt;&lt;/a&gt;&lt;br&gt;
6.10.Once you save the configuration in the Test action, you have to save the stage:&lt;br&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%2Fprldosxlu10vge8q1yuu.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%2Fprldosxlu10vge8q1yuu.png" alt="Image description" width="800" height="171"&gt;&lt;/a&gt;&lt;br&gt;
6.11.Finally, save the pipeline:&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%2Fpjs48w4jldkio22lm74n.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%2Fpjs48w4jldkio22lm74n.png" alt="Image description" width="800" height="174"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Run CI/CD&lt;/strong&gt;&lt;br&gt;
7.Once you have created the pipeline in CodePipeline, the next step is to run it. Remember that we configured the pipeline so that CloudWatch Events automatically run the pipeline every time there is a change in the CodeCommit repository. To disable this automatic process, you can go to EventBridge and disable the rule.&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%2Fdr1zeq825z2jnikk72o3.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%2Fdr1zeq825z2jnikk72o3.png" alt="Image description" width="800" height="481"&gt;&lt;/a&gt;&lt;br&gt;
7.1.Run the pipeline:&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%2Fyhj1lfc5k0epderpr95o.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%2Fyhj1lfc5k0epderpr95o.png" alt="Image description" width="800" height="242"&gt;&lt;/a&gt;&lt;br&gt;
7.2.Wait for the execution to finish and perform the validations:&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%2Ftkvw813eborz5jk3c4o1.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%2Ftkvw813eborz5jk3c4o1.png" alt="Image description" width="800" height="333"&gt;&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%2F8ujjr57adggl4txp3h99.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%2F8ujjr57adggl4txp3h99.png" alt="Image description" width="800" height="240"&gt;&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%2Fw372gxhu8o8xk8fte845.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%2Fw372gxhu8o8xk8fte845.png" alt="Image description" width="800" height="262"&gt;&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%2Fu97xksq4wx6e9onay1w6.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%2Fu97xksq4wx6e9onay1w6.png" alt="Image description" width="800" height="155"&gt;&lt;/a&gt;&lt;br&gt;
7.3.In the delegated or root account, review the StackSets operations:&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%2Fm25ozlnlh72566fwjn8w.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%2Fm25ozlnlh72566fwjn8w.png" alt="Image description" width="800" height="440"&gt;&lt;/a&gt;&lt;br&gt;
7.4.Finally, in the destination account, check the stacks:&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%2Fgv2cmpojmzlofe9w37tx.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%2Fgv2cmpojmzlofe9w37tx.png" alt="Image description" width="800" height="449"&gt;&lt;/a&gt;&lt;br&gt;
I hope that this article will be of great help to you. A big hug and see you another time. Thank you!&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cloudformation</category>
      <category>cicd</category>
      <category>codepipeline</category>
    </item>
    <item>
      <title>AWS CloudFormation + Nested Stacks</title>
      <dc:creator>Frank Pimienta</dc:creator>
      <pubDate>Fri, 16 Sep 2022 01:32:54 +0000</pubDate>
      <link>https://dev.to/frankpimienta/aws-cloudformation-nested-stacks-9k5</link>
      <guid>https://dev.to/frankpimienta/aws-cloudformation-nested-stacks-9k5</guid>
      <description>&lt;p&gt;I want to share with you a current topic, which is the process of managing and provisioning IT infrastructures with IaC (Infrastructure as Code). The main goal of IaC is to automate much of the architecture and management of the IT infrastructure. In addition, it allows you to quickly replicate your infrastructure, record resource changes in detail, and establish a flexible workflow that facilitates the collaboration of all those involved in the development process.&lt;/p&gt;

&lt;p&gt;This concept did not arise with the cloud and DevOps, as some belief but instead has its roots in managing on-premises systems. Many tools, such as Terraform, Ansible, Chef Infra, and Puppet, fulfill the provisioning and automation capabilities. Still, since the blog will mainly focus on Amazon Web Services, I will talk about the native service of AWS for IaC: AWS CloudFormation.&lt;/p&gt;

&lt;p&gt;I'm not going to talk about the structure of an AWS CloudFormation template, there's quite a lot of documentation about it, but today I'm going to talk about Nested Stacks.&lt;/p&gt;

&lt;p&gt;For many people, the simplest way to use AWS CloudFormation is to create a single template in which you define all the resources you want to make. But as your infrastructure or project grows, your templates grow in resources, which means more lines of code. Having such a large template, it becomes difficult to manage.&lt;/p&gt;

&lt;p&gt;In this case, I recommend dividing your templates into smaller ones to manage them more efficiently; that is where Nested Stack comes in.&lt;/p&gt;

&lt;p&gt;But you should know that AWS CloudFormation provides two different methods to manage your templates: Cross-stack and Nested Stacks. &lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Cross-stack&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The concept is straightforward: you manage your stacks separately, export output from one stack, and import it into another.&lt;/p&gt;

&lt;p&gt;For example: In the VPC stack, you want to export the ID, and in the Load Balancer stack, you want to import that exported ID.&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%2Fbf7lw8skmgipkgn99xhf.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%2Fbf7lw8skmgipkgn99xhf.png" alt="Image description" width="488" height="106"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Example code:&lt;/strong&gt;&lt;br&gt;
Export VPC ID:&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%2F56lez21e4930h7bocbxy.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%2F56lez21e4930h7bocbxy.png" alt="Image description" width="392" height="143"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Import VPC ID:&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%2Fqpa9iivbdooyt7a25gk1.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%2Fqpa9iivbdooyt7a25gk1.png" alt="Image description" width="393" height="104"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Nested Stacks&lt;/strong&gt;&lt;br&gt;
Nested Stacks are composed of a root template, the main stack for the first-level stacks. This root template contains the references to the rest of the templates. For those familiar with Terraform, it works like a parent template that calls your public or local modules.&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%2Ftnb36wzlk6eklemcdu1t.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%2Ftnb36wzlk6eklemcdu1t.png" alt="Image description" width="333" height="353"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can upload the individual templates to AWS CloudFormation, but Nested Stacks require templates to be held in an S3 bucket. This is a prerequisite for the Nested Stack to work.&lt;/p&gt;

&lt;p&gt;You can also pass Outputs from one Nested Stack to another in a root template using the Fn::GetAtt intrinsic function. Output values can only be used between Nested Stacks, while Export (Cross-stack) values can be imported into other templates outside the nesting.&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%2Fm7okom1nt3n69d6pr6yp.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%2Fm7okom1nt3n69d6pr6yp.png" alt="Image description" width="521" height="445"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Example code:&lt;/strong&gt;&lt;br&gt;
The stack, named VPCStack, contains the output of the VPC ID.&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%2Fus8rbr0w25ltncuc6qsd.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%2Fus8rbr0w25ltncuc6qsd.png" alt="Image description" width="313" height="169"&gt;&lt;/a&gt;&lt;br&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%2F9xa5o30msx6e8zohveho.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%2F9xa5o30msx6e8zohveho.png" alt="Image description" width="492" height="186"&gt;&lt;/a&gt;&lt;br&gt;
Stack called NACLStack, gets the VPC ID with the GetAtt function.&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%2F0mi6lvamkgg1c90zc60d.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%2F0mi6lvamkgg1c90zc60d.png" alt="Image description" width="503" height="268"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Can Nested Stack and Cross-stack be mixed?&lt;/strong&gt;&lt;br&gt;
Yes, it is usual to mix them in large infrastructures, where there are several types of services, and each service is represented by a root template and its set of nested stacks.&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%2Fwbpz9crq72z9y2p9sxzj.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%2Fwbpz9crq72z9y2p9sxzj.png" alt="Image description" width="800" height="335"&gt;&lt;/a&gt;&lt;br&gt;
I hope that this article will be of great help to you. A big hug and see you another time. Thank you!&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cloudformation</category>
      <category>iac</category>
    </item>
  </channel>
</rss>
