Skip to content

Latest commit

 

History

History
322 lines (261 loc) · 14.8 KB

README.md

File metadata and controls

322 lines (261 loc) · 14.8 KB

Atlantis on AWS Fargate Terraform Module

Fork Changes:

  • Must pass a Security Group in for attaching to the ALB
    • Must allow ingress to 443 from your trusted IPs and all GitHub webhook IPs
    • Must allow egress to all IPs
    • Ideally all ingress and egress allows IPv4 and IPv6, but that is up to you
  • Doesn't respond on port 80 or forward to 443 (use HSTS instead)
  • Must pass a list of trusted IPs to grant access to Atlantis
    • The list of trusted IPs can't be longer than ALB's allowance for a rule (five)
  • Switches to ARM64 for lower cost
  • Enables container egress on IPv6
  • Reduces CPU/Memory defaults to dramatically lower cost
  • Disables container insights to dramatically lower cost

Recommended settings for use of this modified module:

module "atlantis" {
  # All the other required config
  
  # Assumes you have created `aws_security_group.alb.id` per above bullets
  alb_security_group_id = aws_security_group.alb.id

  alb = {
    create_security_group = false
    security_groups       = [
      aws_security_group.alb.id
    ]
  }
}

Back to original README

SWUbanner

Atlantis is tool which provides unified workflow for collaborating on Terraform through GitHub, GitLab and Bitbucket Cloud.

Before using Atlantis and the code in this repository, please make sure that you have read and understood the security implications described in the official Atlantis documentation.

Usage

GitHub is shown below in usage examples; however, any git provider supported by Atlantis can be used by simply using the correct Atlantis environment variables and configuring the respective webhook for the given git provider.

See the Supplemental Docs for additional details on integrating with git providers.

GitHub Complete

The Atlantis module creates all resources required to run Atlantis on AWS Fargate.

module "atlantis" {
  source  = "terraform-aws-modules/atlantis/aws"

  name = "atlantis"

  # ECS Container Definition
  atlantis = {
    environment = [
      {
        name  = "ATLANTIS_GH_USER"
        value = "myuser"
      },
      {
        name  = "ATLANTIS_REPO_ALLOWLIST"
        value = "github.com/terraform-aws-modules/*"
      },
    ]
    secrets = [
      {
        name      = "ATLANTIS_GH_TOKEN"
        valueFrom = "arn:aws:secretsmanager:eu-west-1:111122223333:secret:aes256-7g8H9i"
      },
      {
        name      = "ATLANTIS_GH_WEBHOOK_SECRET"
        valueFrom = "arn:aws:secretsmanager:eu-west-1:111122223333:secret:aes192-4D5e6F"
      },
    ]
  }

  # ECS Service
  service = {
    task_exec_secret_arns = [
      "arn:aws:secretsmanager:eu-west-1:111122223333:secret:aes256-7g8H9i",
      "arn:aws:secretsmanager:eu-west-1:111122223333:secret:aes192-4D5e6F",
    ]
    # Provide Atlantis permission necessary to create/destroy resources
    tasks_iam_role_policies = {
      AdministratorAccess = "arn:aws:iam::aws:policy/AdministratorAccess"
    }
  }
  service_subnets = ["subnet-xyzde987", "subnet-slkjf456", "subnet-qeiru789"]
  vpc_id          = "vpc-1234556abcdef"

  # ALB
  alb_subnets             = ["subnet-abcde012", "subnet-bcde012a", "subnet-fghi345a"]
  certificate_domain_name = "example.com"
  route53_zone_id         = "Z2ES7B9AZ6SHAE"

  tags = {
    Environment = "dev"
    Terraform   = "true"
  }
}

GitHub Separate

The Atlantis module creates most of resources required to run Atlantis on AWS Fargate, except for the ECS Cluster and ALB. This allows you to integrate Atlantis with your existing AWS infrastructure.

module "atlantis" {
  source  = "terraform-aws-modules/atlantis/aws"

  name = "atlantis"

  # Existing cluster
  create_cluster = false
  cluster_arn    = "arn:aws:ecs:eu-west-1:123456789012:cluster/default"

  # Existing ALB
  create_alb            = false
  alb_target_group_arn  = "arn:aws:elasticloadbalancing:eu-west-1:1234567890:targetgroup/bluegreentarget1/209a844cd01825a4"
  alb_security_group_id = "sg-12345678"

  # ECS Container Definition
  atlantis = {
    environment = [
      {
        name  = "ATLANTIS_GH_USER"
        value = "myuser"
      },
      {
        name  = "ATLANTIS_REPO_ALLOWLIST"
        value = "github.com/terraform-aws-modules/*"
      },
    ]
    secrets = [
      {
        name      = "ATLANTIS_GH_TOKEN"
        valueFrom = "arn:aws:secretsmanager:eu-west-1:111122223333:secret:aes256-7g8H9i"
      },
      {
        name      = "ATLANTIS_GH_WEBHOOK_SECRET"
        valueFrom = "arn:aws:secretsmanager:eu-west-1:111122223333:secret:aes192-4D5e6F"
      },
    ]
  }

  # ECS Service
  service = {
    task_exec_secret_arns = [
      "arn:aws:secretsmanager:eu-west-1:111122223333:secret:aes256-7g8H9i",
      "arn:aws:secretsmanager:eu-west-1:111122223333:secret:aes192-4D5e6F",
    ]
    # Provide Atlantis permission necessary to create/destroy resources
    tasks_iam_role_policies = {
      AdministratorAccess = "arn:aws:iam::aws:policy/AdministratorAccess"
    }
  }
  service_subnets = ["subnet-xyzde987", "subnet-slkjf456", "subnet-qeiru789"]
  vpc_id          = "vpc-1234556abcdef"

  tags = {
    Environment = "dev"
    Terraform   = "true"
  }
}

Utilize EFS for Persistent Storage

You can enable EFS to ensure that any plan outputs are persisted to EFS in the event that the Atlantis Task is replaced:

```hcl
module "atlantis" {
  source  = "terraform-aws-modules/atlantis/aws"

  # Truncated for brevity ...

  # EFS
  enable_efs = true
  efs = {
    mount_targets = {
      "eu-west-1a" = {
        subnet_id = "subnet-xyzde987"
      }
      "eu-west-1b" = {
        subnet_id = "subnet-slkjf456"
      }
      "eu-west-1c" = {
        subnet_id = "subnet-qeiru789"
      }
    }
  }
}

Supply Atlantis server configuration

server-atlantis.yaml

repos:
  - id: /.*/
    allow_custom_workflows: true
    allowed_overrides:
      - apply_requirements
      - workflow
    apply_requirements:
      - approved
    workflow: default

main.tf

module "atlantis" {
  source  = "terraform-aws-modules/atlantis/aws"

  # ...

  atlantis = {
    environment = [
      {
        name : "ATLANTIS_REPO_CONFIG_JSON",
        value : jsonencode(yamldecode(file("${path.module}/server-atlantis.yaml"))),
      },
    ]
  }
}

Examples

Requirements

Name Version
terraform >= 1.0
aws >= 5.0

Providers

No providers.

Modules

Name Source Version
acm terraform-aws-modules/acm/aws 5.0.0
alb terraform-aws-modules/alb/aws 9.1.0
ecs_cluster terraform-aws-modules/ecs/aws//modules/cluster 5.6.0
ecs_service terraform-aws-modules/ecs/aws//modules/service 5.6.0
efs terraform-aws-modules/efs/aws 1.3.1

Resources

No resources.

Inputs

Name Description Type Default Required
alb Map of values passed to ALB module definition. See the ALB module for full list of arguments supported any {} no
alb_https_default_action Default action for the ALB https listener any
{
"forward": {
"target_group_key": "atlantis"
}
}
no
alb_security_group_id ID of an existing security group that will be used by ALB. Required if create_alb is false string "" no
alb_subnets List of subnets to place ALB in. Required if create_alb is true list(string) [] no
alb_target_group_arn ARN of an existing ALB target group that will be used to route traffic to the Atlantis service. Required if create_alb is false string "" no
atlantis Map of values passed to Atlantis container definition. See the ECS container definition module for full list of arguments supported any {} no
atlantis_gid GID of the atlantis user number 1000 no
atlantis_uid UID of the atlantis user number 100 no
certificate_arn ARN of certificate issued by AWS ACM. If empty, a new ACM certificate will be created and validated using Route53 DNS string "" no
certificate_domain_name Route53 domain name to use for ACM certificate. Route53 zone for this domain should be created in advance. Specify if it is different from value in route53_zone_name string "" no
cluster Map of values passed to ECS cluster module definition. See the ECS cluster module for full list of arguments supported any {} no
cluster_arn ARN of an existing ECS cluster where resources will be created. Required when create_cluster is false string "" no
create Controls if resources should be created (affects nearly all resources) bool true no
create_alb Determines whether to create an ALB or not bool true no
create_certificate Determines whether to create an ACM certificate or not. If false, certificate_arn must be provided bool true no
create_cluster Whether to create an ECS cluster or not bool true no
create_route53_records Determines whether to create Route53 A and AAAA records for the loadbalancer bool true no
efs Map of values passed to EFS module definition. See the EFS module for full list of arguments supported any {} no
enable_efs Determines whether to create and utilize an EFS filesystem bool false no
name Common name to use on all resources created unless a more specific name is provided string "atlantis" no
route53_record_name Name of Route53 record to create ACM certificate in and main A-record. If null is specified, var.name is used instead. Provide empty string to point root domain name to ALB. string null no
route53_zone_id Route53 zone ID to use for ACM certificate and Route53 records string "" no
service Map of values passed to ECS service module definition. See the ECS service module for full list of arguments supported any {} no
service_subnets List of subnets to place ECS service within list(string) [] no
tags A map of tags to add to all resources map(string) {} no
validate_certificate Determines whether to validate ACM certificate using Route53 DNS. If false, certificate will be created but not validated bool true no
vpc_id ID of the VPC where the resources will be provisioned string "" no

Outputs

Name Description
alb ALB created and all of its associated outputs
cluster ECS cluster created and all of its associated outputs
efs EFS created and all of its associated outputs
service ECS service created and all of its associated outputs
url URL of Atlantis

Authors

Module is maintained by Anton Babenko with help from these awesome contributors.

License

Apache 2 Licensed. See LICENSE for full details.

Additional information for users from Russia and Belarus