{"id":70517,"date":"2025-03-26T16:39:43","date_gmt":"2025-03-26T11:09:43","guid":{"rendered":"https:\/\/www.tothenew.com\/blog\/?p=70517"},"modified":"2025-03-27T13:22:07","modified_gmt":"2025-03-27T07:52:07","slug":"terraform-meets-gitops-setting-up-atlantis-on-aws-for-automated-infrastructure-management","status":"publish","type":"post","link":"https:\/\/www.tothenew.com\/blog\/terraform-meets-gitops-setting-up-atlantis-on-aws-for-automated-infrastructure-management\/","title":{"rendered":"Terraform Meets GitOps: Setting Up Atlantis on AWS for Automated Infrastructure Management"},"content":{"rendered":"<h2><span style=\"color: #000000;\">Introduction<\/span><\/h2>\n<p><span style=\"color: #000000;\">Infrastructure automation is a crucial part of modern <a href=\"https:\/\/www.tothenew.com\/cloud-devops\">DevOps<\/a> workflows, enabling teams to manage cloud resources efficiently using Infrastructure as Code (IaC). <strong>Terraform<\/strong> is a widely used IaC tool, and when paired with <strong>Atlantis<\/strong>, it provides a seamless, GitHub-driven workflow for managing infrastructure changes.<\/span><\/p>\n<p><span style=\"color: #000000;\">Atlantis integrates Terraform with version control systems like <strong>GitHub, GitLab, and Bitbucket<\/strong>, automating Terraform execution when pull requests (PRs) are created. This guide will walk you through setting up <strong>Atlantis<\/strong> on an AWS EC2 instance and integrating it with GitHub for an optimized Terraform automation experience.<\/span><\/p>\n<h2><span style=\"color: #000000;\">Prerequisites<\/span><\/h2>\n<ul>\n<li><span style=\"color: #000000;\"><strong>AWS EC2 Instance<\/strong>: Running Amazon Linux 3, with ports <strong>4000 and 22<\/strong> open.<\/span><\/li>\n<li><span style=\"color: #000000;\"><strong>AWS IAM User<\/strong>: With full access to <strong>S3 and EC2<\/strong>.<\/span><\/li>\n<li><span style=\"color: #000000;\"><strong>GitHub Account<\/strong>: With a private repository for Terraform code.<\/span><\/li>\n<li><span style=\"color: #000000;\"><strong>Basic Knowledge<\/strong>: Familiarity with Linux commands, Terraform, and GitHub workflows.<\/span><\/li>\n<li><span style=\"color: #000000;\"><strong>Required Tools<\/strong>: An SSH client to connect to your EC2 instance and AWS CLI for resource management.<\/span><\/li>\n<\/ul>\n<h2><span style=\"color: #000000;\">Setting Up the EC2 Instance<\/span><\/h2>\n<h3><span style=\"color: #000000;\">1. Launch an EC2 Instance<\/span><\/h3>\n<ol>\n<li><span style=\"color: #000000;\">Log in to <strong>AWS Console<\/strong> and navigate to <strong>EC2<\/strong>.<\/span><\/li>\n<li><span style=\"color: #000000;\">Click <strong>Launch Instance<\/strong> and choose <strong>Amazon Linux 3<\/strong> as the AMI.<\/span><\/li>\n<li><span style=\"color: #000000;\">Select an <strong>Instance Type<\/strong> (e.g., t2.micro or higher).<\/span><\/li>\n<li><span style=\"color: #000000;\">Configure <strong>Security Group<\/strong> to allow inbound traffic on:<\/span>\n<ul>\n<li><span style=\"color: #000000;\">SSH (22)<\/span><\/li>\n<li><span style=\"color: #000000;\">Atlantis (4000)<\/span><\/li>\n<\/ul>\n<\/li>\n<li><span style=\"color: #000000;\">Launch the instance and download the <strong>key pair<\/strong> for SSH access.<\/span><\/li>\n<\/ol>\n<div id=\"attachment_70521\" style=\"width: 898px\" class=\"wp-caption aligncenter\"><img aria-describedby=\"caption-attachment-70521\" decoding=\"async\" loading=\"lazy\" class=\" wp-image-70521\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-13-08-46.png\" alt=\"EC2 image\" width=\"888\" height=\"597\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-13-08-46.png 1464w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-13-08-46-300x202.png 300w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-13-08-46-1024x688.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-13-08-46-768x516.png 768w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-13-08-46-624x419.png 624w\" sizes=\"(max-width: 888px) 100vw, 888px\" \/><p id=\"caption-attachment-70521\" class=\"wp-caption-text\"><span style=\"color: #000000;\">EC2 SG<\/span><\/p><\/div>\n<h3><span style=\"color: #000000;\">2. Connect to the Instance<\/span><\/h3>\n<p><span style=\"color: #000000;\">SSH into the EC2 instance:<\/span><\/p>\n<pre><span style=\"color: #000000;\"><code>ssh -i your-key.pem ec2-user@your-ec2-public-ip<\/code><\/span><\/pre>\n<p><span style=\"color: #000000;\">Update system packages:<\/span><\/p>\n<pre><span style=\"color: #000000;\"><code>sudo yum update -y<\/code><\/span><\/pre>\n<h2><span style=\"color: #000000;\">Installing and Configuring Atlantis on Amazon Linux 3<\/span><\/h2>\n<h3><span style=\"color: #000000;\">1. Install Docker<\/span><\/h3>\n<pre><span style=\"color: #000000;\"><code>sudo yum install -y docker\r\nsudo systemctl start docker\r\nsudo systemctl enable docker<\/code><\/span><\/pre>\n<p><span style=\"color: #000000;\"><img decoding=\"async\" loading=\"lazy\" class=\" wp-image-70569\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-15-19-10.png\" alt=\"Docker Status\" width=\"1776\" height=\"541\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-15-19-10.png 1914w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-15-19-10-300x91.png 300w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-15-19-10-1024x312.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-15-19-10-768x234.png 768w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-15-19-10-1536x468.png 1536w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-15-19-10-624x190.png 624w\" sizes=\"(max-width: 1776px) 100vw, 1776px\" \/><\/span><\/p>\n<p><span style=\"color: #000000;\">Verify Docker installation:<\/span><\/p>\n<pre><span style=\"color: #000000;\"><code>docker --version<\/code><\/span><\/pre>\n<div id=\"attachment_70534\" style=\"width: 586px\" class=\"wp-caption aligncenter\"><img aria-describedby=\"caption-attachment-70534\" decoding=\"async\" loading=\"lazy\" class=\" wp-image-70534\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-13-43-27.png\" alt=\"Docker Version\" width=\"576\" height=\"104\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-13-43-27.png 404w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-13-43-27-300x54.png 300w\" sizes=\"(max-width: 576px) 100vw, 576px\" \/><p id=\"caption-attachment-70534\" class=\"wp-caption-text\"><span style=\"color: #000000;\">Docker Version<\/span><\/p><\/div>\n<h3><span style=\"color: #000000;\">2. Generate a GitHub Access Token<\/span><\/h3>\n<ol>\n<li><span style=\"color: #000000;\">Go to <strong>GitHub &gt; Settings &gt; Developer Settings &gt; Personal Access Tokens\u00a0<\/strong>or <a style=\"color: #000000;\" href=\"https:\/\/github.com\/settings\/tokens\">click here<\/a><\/span><\/li>\n<li><span style=\"color: #000000;\">Click <strong>Generate new token (classic)<\/strong>.<\/span>\n<div id=\"attachment_70522\" style=\"width: 971px\" class=\"wp-caption aligncenter\"><img aria-describedby=\"caption-attachment-70522\" decoding=\"async\" loading=\"lazy\" class=\" wp-image-70522\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-13-16-25.png\" alt=\"Generate New Token\" width=\"961\" height=\"186\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-13-16-25.png 1478w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-13-16-25-300x58.png 300w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-13-16-25-1024x198.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-13-16-25-768x149.png 768w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-13-16-25-624x121.png 624w\" sizes=\"(max-width: 961px) 100vw, 961px\" \/><p id=\"caption-attachment-70522\" class=\"wp-caption-text\"><span style=\"color: #000000;\">Generate New Token<\/span><\/p><\/div>\n<p><span style=\"color: #000000;\">Now, Enter the name and set the Expiration of the Token &#8211;<\/span><\/p>\n<div id=\"attachment_70523\" style=\"width: 1213px\" class=\"wp-caption aligncenter\"><img aria-describedby=\"caption-attachment-70523\" decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-70523\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-13-20-47.png\" alt=\"Token Name and Expiration\" width=\"1203\" height=\"338\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-13-20-47.png 1203w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-13-20-47-300x84.png 300w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-13-20-47-1024x288.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-13-20-47-768x216.png 768w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-13-20-47-624x175.png 624w\" sizes=\"(max-width: 1203px) 100vw, 1203px\" \/><p id=\"caption-attachment-70523\" class=\"wp-caption-text\"><span style=\"color: #000000;\">Token Name and Expiration<\/span><\/p><\/div>\n<p><span style=\"color: #000000;\">Enable scopes:<\/span><\/p>\n<ol>\n<li><span style=\"color: #000000;\"><code>repo<\/code> (repository access)<\/span><\/li>\n<li><span style=\"color: #000000;\"><code>admin:repo_hook<\/code> (webhook permissions)<\/span>\n<p><div id=\"attachment_70524\" style=\"width: 673px\" class=\"wp-caption aligncenter\"><img aria-describedby=\"caption-attachment-70524\" decoding=\"async\" loading=\"lazy\" class=\" wp-image-70524\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-13-22-34.png\" alt=\"Select scopes\" width=\"663\" height=\"575\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-13-22-34.png 879w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-13-22-34-300x260.png 300w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-13-22-34-768x666.png 768w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-13-22-34-624x541.png 624w\" sizes=\"(max-width: 663px) 100vw, 663px\" \/><p id=\"caption-attachment-70524\" class=\"wp-caption-text\"><span style=\"color: #000000;\">Select scopes<\/span><\/p><\/div><\/li>\n<\/ol>\n<\/li>\n<li><span style=\"color: #000000;\">Click <strong>Generate token<\/strong> and copy it (GitHub will not show it again).<\/span>\n<div id=\"attachment_70525\" style=\"width: 681px\" class=\"wp-caption aligncenter\"><img aria-describedby=\"caption-attachment-70525\" decoding=\"async\" loading=\"lazy\" class=\" wp-image-70525\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-13-24-13.png\" alt=\"Generate Token\" width=\"671\" height=\"380\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-13-24-13.png 926w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-13-24-13-300x170.png 300w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-13-24-13-768x435.png 768w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-13-24-13-624x353.png 624w\" sizes=\"(max-width: 671px) 100vw, 671px\" \/><p id=\"caption-attachment-70525\" class=\"wp-caption-text\"><span style=\"color: #000000;\">Generate Token<\/span><\/p><\/div>\n<p><div id=\"attachment_70526\" style=\"width: 970px\" class=\"wp-caption aligncenter\"><img aria-describedby=\"caption-attachment-70526\" decoding=\"async\" loading=\"lazy\" class=\" wp-image-70526\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-13-25-57.png\" alt=\"Token\" width=\"960\" height=\"223\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-13-25-57.png 1429w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-13-25-57-300x70.png 300w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-13-25-57-1024x238.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-13-25-57-768x178.png 768w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-13-25-57-624x145.png 624w\" sizes=\"(max-width: 960px) 100vw, 960px\" \/><p id=\"caption-attachment-70526\" class=\"wp-caption-text\"><span style=\"color: #000000;\">Token<\/span><\/p><\/div><\/li>\n<\/ol>\n<h3><span style=\"color: #000000;\">3. Run the Atlantis Docker Container<\/span><\/h3>\n<pre><span style=\"color: #000000;\"><code>sudo vi Dockerfile<\/code><\/span><\/pre>\n<p><span style=\"color: #000000;\">Paste the following content:<\/span><\/p>\n<pre><span style=\"color: #000000;\"><code>FROM ghcr.io\/runatlantis\/atlantis:latest\r\n\r\nUSER root\r\nRUN apk add --no-cache aws-cli\r\n\r\n# Ensure the 'atlantis' user exists before changing ownership\r\nRUN id atlantis || adduser -D atlantis\r\n\r\nRUN mkdir -p \/home\/atlantis\/.aws\r\nRUN touch \/home\/atlantis\/.aws\/credentials\r\n\r\nRUN chown -R atlantis:atlantis \/home\/atlantis\/\r\n\r\nUSER atlantis\r\n<\/code><\/span><\/pre>\n<div id=\"attachment_70535\" style=\"width: 681px\" class=\"wp-caption aligncenter\"><img aria-describedby=\"caption-attachment-70535\" decoding=\"async\" loading=\"lazy\" class=\" wp-image-70535\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-13-45-54.png\" alt=\"Dockerfile\" width=\"671\" height=\"597\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-13-45-54.png 691w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-13-45-54-300x267.png 300w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-13-45-54-624x555.png 624w\" sizes=\"(max-width: 671px) 100vw, 671px\" \/><p id=\"caption-attachment-70535\" class=\"wp-caption-text\"><span style=\"color: #000000;\">Dockerfile<\/span><\/p><\/div>\n<p><span style=\"color: #000000;\">Save the file and build the Atlantis image:<\/span><\/p>\n<pre><span style=\"color: #000000;\"><code>docker build -t atlantis .<\/code><\/span><\/pre>\n<div id=\"attachment_70546\" style=\"width: 1272px\" class=\"wp-caption aligncenter\"><img aria-describedby=\"caption-attachment-70546\" decoding=\"async\" loading=\"lazy\" class=\" wp-image-70546\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-14-17-01.png\" alt=\"Atlantis Docker image \" width=\"1262\" height=\"587\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-14-17-01.png 1264w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-14-17-01-300x140.png 300w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-14-17-01-1024x476.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-14-17-01-768x357.png 768w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-14-17-01-624x290.png 624w\" sizes=\"(max-width: 1262px) 100vw, 1262px\" \/><p id=\"caption-attachment-70546\" class=\"wp-caption-text\"><span style=\"color: #000000;\">Atlantis Docker image<\/span><\/p><\/div>\n<p><span style=\"color: #000000;\">Run the Atlantis container:<\/span><\/p>\n<pre><span style=\"color: #000000;\">docker run -itd -p 4000:4141 --name atlantis atlantis server --automerge --autoplan-modules --gh-user=&lt;github-account-username&gt; --gh-token=&lt;github-usr-access-token&gt; --repo-allowlist=&lt;list of allowed repos&gt;<\/span><\/pre>\n<div id=\"attachment_70544\" style=\"width: 1930px\" class=\"wp-caption aligncenter\"><img aria-describedby=\"caption-attachment-70544\" decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-70544\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-14-09-04.png\" alt=\"Atlantis container creation\" width=\"1920\" height=\"492\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-14-09-04.png 1920w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-14-09-04-300x77.png 300w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-14-09-04-1024x262.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-14-09-04-768x197.png 768w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-14-09-04-1536x394.png 1536w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-14-09-04-624x160.png 624w\" sizes=\"(max-width: 1920px) 100vw, 1920px\" \/><p id=\"caption-attachment-70544\" class=\"wp-caption-text\"><span style=\"color: #000000;\">Atlantis container creation<\/span><\/p><\/div>\n<h2><span style=\"color: #000000;\">Configuring AWS in Atlantis Docker Container<\/span><\/h2>\n<p><span style=\"color: #000000;\">To allow Atlantis to interact with AWS, create an IAM user with S3 and EC2 full access:<\/span><\/p>\n<ul>\n<li><span style=\"color: #000000;\">Go to AWS IAM &gt; Users &gt; Create User.<\/span><\/li>\n<li><span style=\"color: #000000;\">Attach <strong>AmazonS3FullAccess<\/strong> and <strong>AmazonEC2FullAccess<\/strong> policies.<\/span><\/li>\n<li><span style=\"color: #000000;\">Generate and save the <strong>Access Key<\/strong> and <strong>Secret Key<\/strong>.<\/span><\/li>\n<\/ul>\n<p><span style=\"color: #000000;\">Next, configure AWS credentials inside the Atlantis Docker container by running the following command on your EC2 instance:<\/span><\/p>\n<pre><span style=\"color: #000000;\"><code>docker exec -it atlantis \/bin\/sh<\/code><\/span><\/pre>\n<p><span style=\"color: #000000;\">Once inside the container, open the AWS credentials file for editing:<\/span><\/p>\n<pre><span style=\"color: #000000;\"><code>vi \/home\/atlantis\/.aws\/credentials<\/code><\/span><\/pre>\n<p><span style=\"color: #000000;\">Add the following lines to the credentials file and save it:<\/span><\/p>\n<pre><span style=\"color: #000000;\"><code>[default]\r\naws_access_key_id = YOUR_ACCESS_KEY\r\naws_secret_access_key = YOUR_SECRET_KEY\r\n<\/code><\/span><\/pre>\n<p><span style=\"color: #000000;\">Replace the placeholders with your IAM user credentials:<\/span><\/p>\n<p><span style=\"color: #000000;\">YOUR_ACCESS_KEY: Access key ID of the AWS IAM user.<\/span><br \/>\n<span style=\"color: #000000;\">YOUR_SECRET_KEY: Secret access key ID of the AWS IAM user.<\/span><\/p>\n<blockquote><p><span style=\"color: #000000;\"><strong>Important Security Note: <\/strong>Storing AWS access keys directly on an EC2 instance is not recommended for production environments due to security risks. This setup is demonstrated here for educational purposes only. In a real-world scenario, consider using AWS IAM roles with EC2 instance profiles or AWS Secrets Manager to securely manage credentials.<\/span><\/p><\/blockquote>\n<p><span style=\"color: #000000;\"><strong>Note<\/strong>: If you have multiple AWS profiles, you can add additional profile entries in the credentials file and specify them in your Terraform configuration.<\/span><\/p>\n<h2><span style=\"color: #000000;\">Configuring Webhooks in GitHub Repository<\/span><\/h2>\n<p><span style=\"color: #000000;\">Webhooks allow Atlantis to react to pull request events and apply Terraform changes automatically. Follow these steps to set up a webhook in your GitHub repository:<\/span><\/p>\n<ol>\n<li style=\"list-style-type: none;\">\n<ol>\n<li><span style=\"color: #000000;\">Open your GitHub repository that contains your Terraform code.<\/span><\/li>\n<li><span style=\"color: #000000;\">Go to <strong>Settings<\/strong> \u2192 <strong>Webhooks<\/strong>.<\/span><\/li>\n<li><span style=\"color: #000000;\">Click <strong>Add webhook<\/strong>.<\/span><\/li>\n<li><span style=\"color: #000000;\">Set the <strong>Payload URL<\/strong> to:<\/span><\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<pre><span style=\"color: #000000;\"><code>http:\/\/your-ec2-public-ip:4000\/events<\/code><\/span><\/pre>\n<ol>\n<li><span style=\"color: #000000;\">Set <strong>Content type<\/strong> to <code>application\/json<\/code>.<img decoding=\"async\" loading=\"lazy\" class=\"wp-image-70548 size-full\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-14-30-08.png\" alt=\"Webhook name\" width=\"1205\" height=\"969\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-14-30-08.png 1205w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-14-30-08-300x241.png 300w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-14-30-08-1024x823.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-14-30-08-768x618.png 768w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-14-30-08-624x502.png 624w\" sizes=\"(max-width: 1205px) 100vw, 1205px\" \/><br \/>\n<\/span><\/li>\n<li><span style=\"color: #000000;\">Select <strong>Let me select individual events<\/strong> and check the following options:<\/span>\n<ul>\n<li><span style=\"color: #000000;\">Issue comments<\/span><\/li>\n<li><span style=\"color: #000000;\">Pull request reviews<\/span><\/li>\n<li><span style=\"color: #000000;\">Pull requests<\/span><\/li>\n<li><span style=\"color: #000000;\">Pushes<\/span>\n<p><div id=\"attachment_70549\" style=\"width: 751px\" class=\"wp-caption aligncenter\"><img aria-describedby=\"caption-attachment-70549\" decoding=\"async\" loading=\"lazy\" class=\" wp-image-70549\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-14-32-35.png\" alt=\"Events Selection\" width=\"741\" height=\"905\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-14-32-35.png 779w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-14-32-35-246x300.png 246w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-14-32-35-768x938.png 768w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-14-32-35-624x762.png 624w\" sizes=\"(max-width: 741px) 100vw, 741px\" \/><p id=\"caption-attachment-70549\" class=\"wp-caption-text\"><span style=\"color: #000000;\">Events Selection<\/span><\/p><\/div><\/li>\n<\/ul>\n<\/li>\n<li><span style=\"color: #000000;\">Ensure that <strong>Active<\/strong> is checked.<\/span><br \/>\n<span style=\"color: #000000;\"><img decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-70550 aligncenter\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-14-33-54.png\" alt=\"Active is Checked\" width=\"773\" height=\"612\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-14-33-54.png 773w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-14-33-54-300x238.png 300w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-14-33-54-768x608.png 768w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-14-33-54-624x494.png 624w\" sizes=\"(max-width: 773px) 100vw, 773px\" \/><\/span><\/li>\n<li><span style=\"color: #000000;\">Click <strong>Add webhook<\/strong>.<\/span><\/li>\n<\/ol>\n<p><span style=\"color: #000000;\">Now, every time a pull request is created, updated, or merged, Atlantis will receive an event and execute the relevant Terraform workflow.<\/span><\/p>\n<h2><span style=\"color: #000000;\">Running Terraform Workflow with Atlantis<\/span><\/h2>\n<ol>\n<li style=\"list-style-type: none;\">\n<ol>\n<li><span style=\"color: #000000;\"><strong>Create a new pull request<\/strong> in GitHub.<\/span>\n<p><div id=\"attachment_70552\" style=\"width: 1677px\" class=\"wp-caption aligncenter\"><img aria-describedby=\"caption-attachment-70552\" decoding=\"async\" loading=\"lazy\" class=\"wp-image-70552 size-full\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-14-38-19.png\" alt=\"Create Pull Request\" width=\"1667\" height=\"799\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-14-38-19.png 1667w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-14-38-19-300x144.png 300w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-14-38-19-1024x491.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-14-38-19-768x368.png 768w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-14-38-19-1536x736.png 1536w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-14-38-19-624x299.png 624w\" sizes=\"(max-width: 1667px) 100vw, 1667px\" \/><p id=\"caption-attachment-70552\" class=\"wp-caption-text\"><span style=\"color: #000000;\">Create Pull Request<\/span><\/p><\/div><\/li>\n<li><span style=\"color: #000000;\">Atlantis will <strong>automatically run<\/strong> <code>terraform plan<\/code>.<\/span>\n<div id=\"attachment_70553\" style=\"width: 1604px\" class=\"wp-caption aligncenter\"><img aria-describedby=\"caption-attachment-70553\" decoding=\"async\" loading=\"lazy\" class=\"wp-image-70553 size-full\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-14-47-00.png\" alt=\"Atlantis plan\" width=\"1594\" height=\"1037\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-14-47-00.png 1594w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-14-47-00-300x195.png 300w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-14-47-00-1024x666.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-14-47-00-768x500.png 768w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-14-47-00-1536x999.png 1536w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-14-47-00-624x406.png 624w\" sizes=\"(max-width: 1594px) 100vw, 1594px\" \/><p id=\"caption-attachment-70553\" class=\"wp-caption-text\"><span style=\"color: #000000;\">Atlantis plan<\/span><\/p><\/div>\n<p><span style=\"color: #000000;\"><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter wp-image-70555\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-14-49-43.png\" alt=\"\" width=\"687\" height=\"879\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-14-49-43.png 849w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-14-49-43-234x300.png 234w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-14-49-43-800x1024.png 800w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-14-49-43-768x983.png 768w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-14-49-43-624x799.png 624w\" sizes=\"(max-width: 687px) 100vw, 687px\" \/><\/span><br \/>\n<span style=\"color: #000000;\">We can use the <strong>Show output\u00a0<\/strong>option to see the output of the <strong>terraform plan<\/strong> command &#8211;<\/span><\/p>\n<p><div id=\"attachment_70556\" style=\"width: 859px\" class=\"wp-caption aligncenter\"><img aria-describedby=\"caption-attachment-70556\" decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-70556\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-14-53-06.png\" alt=\"Output of Terraform Plan\" width=\"849\" height=\"1087\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-14-53-06.png 849w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-14-53-06-234x300.png 234w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-14-53-06-800x1024.png 800w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-14-53-06-768x983.png 768w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-14-53-06-624x799.png 624w\" sizes=\"(max-width: 849px) 100vw, 849px\" \/><p id=\"caption-attachment-70556\" class=\"wp-caption-text\"><span style=\"color: #000000;\">Output of Terraform Plan<\/span><\/p><\/div><\/li>\n<li><span style=\"color: #000000;\">To apply changes, <strong>comment<\/strong>:<\/span><\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<pre><span style=\"color: #000000;\">atlantis apply -d .<\/span><\/pre>\n<div id=\"attachment_70557\" style=\"width: 927px\" class=\"wp-caption aligncenter\"><img aria-describedby=\"caption-attachment-70557\" decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-70557\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-14-56-36.png\" alt=\"Terraform apply\" width=\"917\" height=\"986\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-14-56-36.png 917w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-14-56-36-279x300.png 279w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-14-56-36-768x826.png 768w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-14-56-36-624x671.png 624w\" sizes=\"(max-width: 917px) 100vw, 917px\" \/><p id=\"caption-attachment-70557\" class=\"wp-caption-text\"><span style=\"color: #000000;\">Terraform apply<\/span><\/p><\/div>\n<ol>\n<li><span style=\"color: #000000;\">Once applied, You can check <strong>AWS Console<\/strong> for created resources.<\/span>\n<p><div id=\"attachment_70562\" style=\"width: 1666px\" class=\"wp-caption aligncenter\"><img aria-describedby=\"caption-attachment-70562\" decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-70562\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-15-05-12.png\" alt=\"AWS Resource\" width=\"1656\" height=\"489\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-15-05-12.png 1656w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-15-05-12-300x89.png 300w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-15-05-12-1024x302.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-15-05-12-768x227.png 768w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-15-05-12-1536x454.png 1536w, \/blog\/wp-ttn-blog\/uploads\/2025\/03\/Screenshot-from-2025-03-17-15-05-12-624x184.png 624w\" sizes=\"(max-width: 1656px) 100vw, 1656px\" \/><p id=\"caption-attachment-70562\" class=\"wp-caption-text\"><span style=\"color: #000000;\">AWS Resource<\/span><\/p><\/div><\/li>\n<\/ol>\n<h2><span style=\"color: #000000;\">Conclusion<\/span><\/h2>\n<p><span style=\"color: #000000;\">By using Terraform with Atlantis and GitHub, teams can automate infrastructure updates while maintaining security, efficiency, and teamwork. With Atlantis, changes go through a pull request process, ensuring they are reviewed and approved before being deployed.<\/span><\/p>\n<p><span style=\"color: #000000;\">One of the key benefits of Atlantis is that it locks the state file while a pull request is open. This helps keep things secure by preventing multiple users from making changes at the same time, reducing the risk of state file issues.<\/span><\/p>\n<h2><span style=\"color: #000000;\">FAQs<\/span><\/h2>\n<ul>\n<li><span style=\"color: #000000;\"><strong>How does Atlantis compare to Terraform Cloud?<\/strong> &#8211; Atlantis is <strong>self-hosted and free<\/strong>, while Terraform Cloud has associated costs.<\/span><\/li>\n<li><span style=\"color: #000000;\"><strong>Is Atlantis suitable for large infrastructures?<\/strong> &#8211; Yes, it supports <strong>multi-repository environments<\/strong>.<\/span><\/li>\n<li><span style=\"color: #000000;\"><strong>Can I integrate Atlantis with CI\/CD tools?<\/strong> &#8211; Yes, it can be integrated with Jenkins, GitHub Actions, etc.<\/span><\/li>\n<li><span style=\"color: #000000;\"><strong>How do I troubleshoot Atlantis setup issues?<\/strong> &#8211; Check logs using <code>docker logs atlantis<\/code>.<\/span><\/li>\n<li><span style=\"color: #000000;\"><strong>Is Atlantis secure?<\/strong> &#8211; Yes, when properly configured with <strong>IAM policies and security groups<\/strong>.<\/span><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Introduction Infrastructure automation is a crucial part of modern DevOps workflows, enabling teams to manage cloud resources efficiently using Infrastructure as Code (IaC). Terraform is a widely used IaC tool, and when paired with Atlantis, it provides a seamless, GitHub-driven workflow for managing infrastructure changes. Atlantis integrates Terraform with version control systems like GitHub, GitLab, [&hellip;]<\/p>\n","protected":false},"author":1834,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"iawp_total_views":228},"categories":[5877],"tags":[7162,5627,6835,1585,7166],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/70517"}],"collection":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/users\/1834"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/comments?post=70517"}],"version-history":[{"count":29,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/70517\/revisions"}],"predecessor-version":[{"id":71208,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/70517\/revisions\/71208"}],"wp:attachment":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/media?parent=70517"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/categories?post=70517"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/tags?post=70517"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}