{"id":20169230,"url":"https://github.com/clientio/appmixer-module-aws","last_synced_at":"2025-06-13T07:34:51.610Z","repository":{"id":229706010,"uuid":"725762000","full_name":"clientIO/appmixer-module-aws","owner":"clientIO","description":"Appmixer Infrastructure-as-Code Terraform module for AWS.","archived":false,"fork":false,"pushed_at":"2025-04-23T10:07:24.000Z","size":314,"stargazers_count":0,"open_issues_count":2,"forks_count":0,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-04-23T11:22:41.905Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"HCL","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/clientIO.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":".github/CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":".github/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-11-30T20:26:32.000Z","updated_at":"2025-04-23T10:07:30.000Z","dependencies_parsed_at":"2024-03-25T22:25:08.172Z","dependency_job_id":"7559b20f-294b-42fb-ab1d-931763f8f1a9","html_url":"https://github.com/clientIO/appmixer-module-aws","commit_stats":null,"previous_names":["clientio/appmixer-module-aws"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/clientIO/appmixer-module-aws","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clientIO%2Fappmixer-module-aws","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clientIO%2Fappmixer-module-aws/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clientIO%2Fappmixer-module-aws/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clientIO%2Fappmixer-module-aws/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/clientIO","download_url":"https://codeload.github.com/clientIO/appmixer-module-aws/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clientIO%2Fappmixer-module-aws/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259602890,"owners_count":22883061,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-14T01:11:49.188Z","updated_at":"2025-06-13T07:34:51.563Z","avatar_url":"https://github.com/clientIO.png","language":"HCL","readme":"# [\u003cimg src=\"https://avatars.githubusercontent.com/u/882337\" width=30px\u003e](https://www.appmixer.com/) AWS Appmixer Terraform module\n\n\n[![Terraform validate](https://github.com/clientIO/appmixer-module-aws/actions/workflows/validate.yaml/badge.svg)](https://github.com/clientIO/appmixer-module-aws/actions/workflows/validate.yaml)\n[![pre-commit](https://github.com/clientIO/appmixer-module-aws/actions/workflows/pre-commit.yml/badge.svg)](https://github.com/clientIO/appmixer-module-aws/actions/workflows/pre-commit.yml)\n\n## Description\nA Terraform module to provision appmixer application.\n\n## Configuration\n\n### Autoscaling configuration\nAutoscaling is configured using `ecs_autoscaling_config` variable which by default defines two [capacity providers](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/cluster-capacity-providers.html) used while scaling the cluster.\n - `on_demand` - capacity provider alocates on demand EC2 instances which are more expensive but are always available\n - `spot` - capacity provider alocates spot EC2 instances which are cheaper but can be terminated at any time, therefore it is recommended to use spot instances as temporary capacity\n\n To see more info about capacity provider configuration see [aws_autoscaling_group configuration](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/autoscaling_group)\n\n\u003e [!IMPORTANT]\n\u003e Correct **Instance types** need to be set. The size of EC2 network interfaces (ENIs) for each instance type is restricted and this limitation is directly tied to the number of containers that can be executed on the instance. To avoid this limitation, consider using instance types that allow so-called `ENI Trunking` meaning EC2 can attach more network interfaces (see more [AWS Docs](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/container-instance-eni.html)) Also ENI Trunking **must be allowed** in AWS account ([AWS ECS]( https://console.aws.amazon.com/ecs/v2) -\u003e Account Settings -\u003e AWSVPC Trunking -\u003e Enable)\n\n### Managed services\nRabbitMQ, Opensearch (Elasticsearch), ElasticCache (Redis), DocumentDB(Mongo) are managed by AWS and can be configured through variables:\n- `document_db`\n- `elasticache`\n- `elasticsearch`\n- `rabbitmq`\n\nEach service is running with minimal configuration, in production they might need some resizing.\n\n\u003e [!NOTE]\n\u003e Within this module, managed services can be created separately and incorporated using the e.g. `external_elasticache` variable, for instance. It is crucial in this setup to verify the correct configuration of all network and security policies.\n\n\n### User initialization\nAdmin user is initialized through automated task running in ECS. Variable `init_user` needs to be set.\n\n\n### Deployment \u0026 Upgrade\n- the service `engine` is waiting for creation of index in DocumentDB which might take around 20min till service become available, therefore the **User initialization** will fail and needs to be repeated by running `terraform plan` again\n\n\n## Examples\n- See [Development example](examples/development/README.md) for further information. (Minimal setup)\n- See [Production example](examples/production/README.md) for further information. (High available setup)\n\n## Pricing\n[AWS Pricing estimation](https://calculator.aws/#/estimate?id=255bd4b7f28f0aadd6dcc8e746b475ea18fd2779) for each environemnt.\nPricing can vary based on real traffic.\n\n- Development ~ 450$/month\n- Production  ~ 900$/month\n\n## Simple VPN\nYou can use [sshuttle](https://github.com/sshuttle/sshuttle) to connect to private VPC network.\n1. Run EC2 with configured SSH keys in your public subnet\n2. Install `sshuttle`\n3. Connect through `sshuttle` to your running EC2 (`sshuttle -r \u003cSSH_CONFIG\u003e 0.0.0.0/0 -vv`)\n4. Your network traffic should be routed through EC2, you should be able to see managed AWS services running in private subnets.\n\n\n## Architecture\n ![arch-diagram](docs/ecs-diagram.png)\n\n\n\u003c!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK --\u003e\n## Requirements\n\n| Name | Version |\n|------|---------|\n| \u003ca name=\"requirement_terraform\"\u003e\u003c/a\u003e [terraform](#requirement\\_terraform) | \u003e= 1.6.6 |\n| \u003ca name=\"requirement_aws\"\u003e\u003c/a\u003e [aws](#requirement\\_aws) | \u003e= 5.32.1 |\n| \u003ca name=\"requirement_http\"\u003e\u003c/a\u003e [http](#requirement\\_http) | 3.4.1 |\n| \u003ca name=\"requirement_random\"\u003e\u003c/a\u003e [random](#requirement\\_random) | \u003e= 3.6.0 |\n\n## Modules\n\n| Name | Source | Version |\n|------|--------|---------|\n| \u003ca name=\"module_alb\"\u003e\u003c/a\u003e [alb](#module\\_alb) | terraform-aws-modules/alb/aws | ~\u003e 9.0 |\n| \u003ca name=\"module_autoscaling\"\u003e\u003c/a\u003e [autoscaling](#module\\_autoscaling) | terraform-aws-modules/autoscaling/aws | ~\u003e 6.5 |\n| \u003ca name=\"module_autoscaling_sg\"\u003e\u003c/a\u003e [autoscaling\\_sg](#module\\_autoscaling\\_sg) | terraform-aws-modules/security-group/aws | ~\u003e 5.0 |\n| \u003ca name=\"module_document_db_ssm_password\"\u003e\u003c/a\u003e [document\\_db\\_ssm\\_password](#module\\_document\\_db\\_ssm\\_password) | cloudposse/ssm-parameter-store/aws | 0.11.0 |\n| \u003ca name=\"module_document_db_ssm_username\"\u003e\u003c/a\u003e [document\\_db\\_ssm\\_username](#module\\_document\\_db\\_ssm\\_username) | cloudposse/ssm-parameter-store/aws | 0.11.0 |\n| \u003ca name=\"module_documentdb_cluster\"\u003e\u003c/a\u003e [documentdb\\_cluster](#module\\_documentdb\\_cluster) | cloudposse/documentdb-cluster/aws | 0.24.0 |\n| \u003ca name=\"module_ecs_cluster\"\u003e\u003c/a\u003e [ecs\\_cluster](#module\\_ecs\\_cluster) | terraform-aws-modules/ecs/aws//modules/cluster | 5.7.4 |\n| \u003ca name=\"module_ecs_service_backoffice\"\u003e\u003c/a\u003e [ecs\\_service\\_backoffice](#module\\_ecs\\_service\\_backoffice) | terraform-aws-modules/ecs/aws//modules/service | 5.7.4 |\n| \u003ca name=\"module_ecs_service_engine\"\u003e\u003c/a\u003e [ecs\\_service\\_engine](#module\\_ecs\\_service\\_engine) | terraform-aws-modules/ecs/aws//modules/service | 5.7.4 |\n| \u003ca name=\"module_ecs_service_frontend\"\u003e\u003c/a\u003e [ecs\\_service\\_frontend](#module\\_ecs\\_service\\_frontend) | terraform-aws-modules/ecs/aws//modules/service | 5.7.4 |\n| \u003ca name=\"module_ecs_service_logstash\"\u003e\u003c/a\u003e [ecs\\_service\\_logstash](#module\\_ecs\\_service\\_logstash) | terraform-aws-modules/ecs/aws//modules/service | 5.7.4 |\n| \u003ca name=\"module_ecs_service_quota\"\u003e\u003c/a\u003e [ecs\\_service\\_quota](#module\\_ecs\\_service\\_quota) | terraform-aws-modules/ecs/aws//modules/service | 5.7.4 |\n| \u003ca name=\"module_elasticache\"\u003e\u003c/a\u003e [elasticache](#module\\_elasticache) | cloudposse/elasticache-redis/aws | 1.0.0 |\n| \u003ca name=\"module_elasticache_ssm_password\"\u003e\u003c/a\u003e [elasticache\\_ssm\\_password](#module\\_elasticache\\_ssm\\_password) | cloudposse/ssm-parameter-store/aws | 0.11.0 |\n| \u003ca name=\"module_elasticsearch\"\u003e\u003c/a\u003e [elasticsearch](#module\\_elasticsearch) | cloudposse/elasticsearch/aws | 0.46.0 |\n| \u003ca name=\"module_elasticsearch_ssm_password\"\u003e\u003c/a\u003e [elasticsearch\\_ssm\\_password](#module\\_elasticsearch\\_ssm\\_password) | cloudposse/ssm-parameter-store/aws | 0.11.0 |\n| \u003ca name=\"module_elasticsearch_ssm_username\"\u003e\u003c/a\u003e [elasticsearch\\_ssm\\_username](#module\\_elasticsearch\\_ssm\\_username) | cloudposse/ssm-parameter-store/aws | 0.11.0 |\n| \u003ca name=\"module_label\"\u003e\u003c/a\u003e [label](#module\\_label) | cloudposse/label/null | 0.25.0 |\n| \u003ca name=\"module_rabbit_mq\"\u003e\u003c/a\u003e [rabbit\\_mq](#module\\_rabbit\\_mq) | cloudposse/mq-broker/aws | 3.1.0 |\n| \u003ca name=\"module_s3_bucket\"\u003e\u003c/a\u003e [s3\\_bucket](#module\\_s3\\_bucket) | cloudposse/s3-bucket/aws | 4.0.1 |\n| \u003ca name=\"module_services_configuration_merge\"\u003e\u003c/a\u003e [services\\_configuration\\_merge](#module\\_services\\_configuration\\_merge) | cloudposse/config/yaml//modules/deepmerge | 1.0.2 |\n| \u003ca name=\"module_sg_document_db_rules\"\u003e\u003c/a\u003e [sg\\_document\\_db\\_rules](#module\\_sg\\_document\\_db\\_rules) | cloudposse/security-group/aws | 2.2.0 |\n| \u003ca name=\"module_sg_user_init\"\u003e\u003c/a\u003e [sg\\_user\\_init](#module\\_sg\\_user\\_init) | cloudposse/security-group/aws | 2.2.0 |\n| \u003ca name=\"module_sq_elasticsearch\"\u003e\u003c/a\u003e [sq\\_elasticsearch](#module\\_sq\\_elasticsearch) | cloudposse/security-group/aws | 2.2.0 |\n| \u003ca name=\"module_subnets\"\u003e\u003c/a\u003e [subnets](#module\\_subnets) | cloudposse/dynamic-subnets/aws | 2.4.1 |\n| \u003ca name=\"module_vpc\"\u003e\u003c/a\u003e [vpc](#module\\_vpc) | cloudposse/vpc/aws | 2.1.1 |\n\n## Resources\n\n| Name | Type |\n|------|------|\n| [aws_acm_certificate.alb](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/acm_certificate) | resource |\n| [aws_acm_certificate_validation.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/acm_certificate_validation) | resource |\n| [aws_cloudwatch_log_group.ecs_mongo_init_user](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group) | resource |\n| [aws_ecs_task_definition.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ecs_task_definition) | resource |\n| [aws_elasticsearch_domain_policy.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/elasticsearch_domain_policy) | resource |\n| [aws_route53_record.alb](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_record) | resource |\n| [aws_route53_record.cert_alb](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_record) | resource |\n| [aws_service_discovery_http_namespace.appmixer](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/service_discovery_http_namespace) | resource |\n| [random_password.elasticsearch_password](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource |\n| [random_password.rabbit_mq](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource |\n| [random_password.redis_password](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource |\n| [random_pet.document_db_username](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/pet) | resource |\n| [random_pet.elasticsearch_username](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/pet) | resource |\n| [aws_ecs_task_execution.run](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ecs_task_execution) | data source |\n| [aws_region.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) | data source |\n| [aws_ssm_parameter.ecs_optimized_ami](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ssm_parameter) | data source |\n| [aws_vpc.external](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/vpc) | data source |\n| [http_http.init_user](https://registry.terraform.io/providers/hashicorp/http/3.4.1/docs/data-sources/http) | data source |\n\n## Inputs\n\n| Name | Description | Type | Default | Required |\n|------|-------------|------|---------|:--------:|\n| \u003ca name=\"input_root_dns_name\"\u003e\u003c/a\u003e [root\\_dns\\_name](#input\\_root\\_dns\\_name) | Root DNS name, must be applicable to route53 zone (zone\\_id) | `string` | n/a | yes |\n| \u003ca name=\"input_additional_security_group_rules\"\u003e\u003c/a\u003e [additional\\_security\\_group\\_rules](#input\\_additional\\_security\\_group\\_rules) | Additional security group rules added to security group rules of all resources, see more [Terraform docs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | \u003cpre\u003elist(object({\u003cbr\u003e    type              = string\u003cbr\u003e    from_port         = number\u003cbr\u003e    to_port           = number\u003cbr\u003e    protocol          = string\u003cbr\u003e    cidr_blocks       = optional(list(string))\u003cbr\u003e    ipv6_cidr_blocks  = optional(list(string))\u003cbr\u003e    security_group_id = optional(string)\u003cbr\u003e  }))\u003c/pre\u003e | `[]` | no |\n| \u003ca name=\"input_alb_ingress_security_group_rules\"\u003e\u003c/a\u003e [alb\\_ingress\\_security\\_group\\_rules](#input\\_alb\\_ingress\\_security\\_group\\_rules) | Application Load Balancer security group ingress rules | \u003cpre\u003emap(object({\u003cbr\u003e    ip_protocol                  = string\u003cbr\u003e    from_port                    = optional(number)\u003cbr\u003e    to_port                      = optional(number)\u003cbr\u003e    referenced_security_group_id = optional(string)\u003cbr\u003e    description                  = optional(string)\u003cbr\u003e    cidr_ipv4                    = optional(string)\u003cbr\u003e    cidr_ipv6                    = optional(string)\u003cbr\u003e  }))\u003c/pre\u003e | \u003cpre\u003e{\u003cbr\u003e  \"all_http\": {\u003cbr\u003e    \"cidr_ipv4\": \"0.0.0.0/0\",\u003cbr\u003e    \"from_port\": 80,\u003cbr\u003e    \"ip_protocol\": \"tcp\",\u003cbr\u003e    \"to_port\": 80\u003cbr\u003e  },\u003cbr\u003e  \"all_https\": {\u003cbr\u003e    \"cidr_ipv4\": \"0.0.0.0/0\",\u003cbr\u003e    \"from_port\": 443,\u003cbr\u003e    \"ip_protocol\": \"tcp\",\u003cbr\u003e    \"to_port\": 443\u003cbr\u003e  }\u003cbr\u003e}\u003c/pre\u003e | no |\n| \u003ca name=\"input_attributes\"\u003e\u003c/a\u003e [attributes](#input\\_attributes) | Additional attributes (e.g. `1`) | `list(string)` | `[]` | no |\n| \u003ca name=\"input_availability_zones\"\u003e\u003c/a\u003e [availability\\_zones](#input\\_availability\\_zones) | List of availability zones | `list(string)` | \u003cpre\u003e[\u003cbr\u003e  \"eu-central-1a\",\u003cbr\u003e  \"eu-central-1b\",\u003cbr\u003e  \"eu-central-1c\"\u003cbr\u003e]\u003c/pre\u003e | no |\n| \u003ca name=\"input_certificate_arn\"\u003e\u003c/a\u003e [certificate\\_arn](#input\\_certificate\\_arn) | Certificate ARN, if not set, certificate will be automatically created using '*.\u003croot\\_dns\\_name\u003e' | `string` | `null` | no |\n| \u003ca name=\"input_document_db\"\u003e\u003c/a\u003e [document\\_db](#input\\_document\\_db) | DocumentDB configuration object | \u003cpre\u003eobject({\u003cbr\u003e    cluster_size   = optional(number, 1)\u003cbr\u003e    cluster_family = optional(string, \"docdb5.0\")\u003cbr\u003e    instance_class = optional(string, \"db.t4g.medium\")\u003cbr\u003e    engine_version = optional(string, \"5.0.0\")\u003cbr\u003e    cluster_parameters = optional(list(object({\u003cbr\u003e      apply_method = string\u003cbr\u003e      name         = string\u003cbr\u003e      value        = string\u003cbr\u003e    })), [])\u003cbr\u003e  })\u003c/pre\u003e | `{}` | no |\n| \u003ca name=\"input_ecs_autoscaling_config\"\u003e\u003c/a\u003e [ecs\\_autoscaling\\_config](#input\\_ecs\\_autoscaling\\_config) | n/a | `any` | \u003cpre\u003e{\u003cbr\u003e  \"on_demand\": {\u003cbr\u003e    \"capacity_provider\": {\u003cbr\u003e      \"default_capacity_provider_strategy\": {\u003cbr\u003e        \"base\": 1,\u003cbr\u003e        \"weight\": 10\u003cbr\u003e      },\u003cbr\u003e      \"maximum_scaling_step_size\": 5,\u003cbr\u003e      \"minimum_scaling_step_size\": 1,\u003cbr\u003e      \"target_capacity\": 100\u003cbr\u003e    },\u003cbr\u003e    \"instance_type\": \"m5.large\",\u003cbr\u003e    \"max_size\": 6,\u003cbr\u003e    \"min_size\": 1,\u003cbr\u003e    \"mixed_instances_policy\": {\u003cbr\u003e      \"instances_distribution\": {\u003cbr\u003e        \"on_demand_allocation_strategy\": \"prioritized\",\u003cbr\u003e        \"on_demand_base_capacity\": 1,\u003cbr\u003e        \"on_demand_percentage_above_base_capacity\": 100,\u003cbr\u003e        \"spot_allocation_strategy\": \"lowest-price\"\u003cbr\u003e      },\u003cbr\u003e      \"override\": [\u003cbr\u003e        {\u003cbr\u003e          \"instance_type\": \"m5.large\",\u003cbr\u003e          \"weighted_capacity\": \"1\"\u003cbr\u003e        },\u003cbr\u003e        {\u003cbr\u003e          \"instance_type\": \"c5.large\",\u003cbr\u003e          \"weighted_capacity\": \"1\"\u003cbr\u003e        }\u003cbr\u003e      ]\u003cbr\u003e    },\u003cbr\u003e    \"use_mixed_instances_policy\": true\u003cbr\u003e  },\u003cbr\u003e  \"spot\": {\u003cbr\u003e    \"capacity_provider\": {\u003cbr\u003e      \"default_capacity_provider_strategy\": {\u003cbr\u003e        \"base\": 0,\u003cbr\u003e        \"weight\": 80\u003cbr\u003e      },\u003cbr\u003e      \"maximum_scaling_step_size\": 5,\u003cbr\u003e      \"minimum_scaling_step_size\": 1,\u003cbr\u003e      \"target_capacity\": 100\u003cbr\u003e    },\u003cbr\u003e    \"instance_type\": \"m5.large\",\u003cbr\u003e    \"max_size\": 6,\u003cbr\u003e    \"min_size\": 1,\u003cbr\u003e    \"mixed_instances_policy\": {\u003cbr\u003e      \"instances_distribution\": {\u003cbr\u003e        \"on_demand_allocation_strategy\": \"prioritized\",\u003cbr\u003e        \"on_demand_base_capacity\": 0,\u003cbr\u003e        \"on_demand_percentage_above_base_capacity\": 0,\u003cbr\u003e        \"spot_allocation_strategy\": \"lowest-price\"\u003cbr\u003e      },\u003cbr\u003e      \"override\": [\u003cbr\u003e        {\u003cbr\u003e          \"instance_type\": \"m5.large\",\u003cbr\u003e          \"weighted_capacity\": \"1\"\u003cbr\u003e        },\u003cbr\u003e        {\u003cbr\u003e          \"instance_type\": \"c5.large\",\u003cbr\u003e          \"weighted_capacity\": \"1\"\u003cbr\u003e        }\u003cbr\u003e      ]\u003cbr\u003e    },\u003cbr\u003e    \"use_mixed_instances_policy\": true\u003cbr\u003e  }\u003cbr\u003e}\u003c/pre\u003e | no |\n| \u003ca name=\"input_ecs_cluster_config\"\u003e\u003c/a\u003e [ecs\\_cluster\\_config](#input\\_ecs\\_cluster\\_config) | Cluster configuration object `execute_command_configuration`,  see more [terraform docs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ecs_cluster) | `any` | \u003cpre\u003e{\u003cbr\u003e  \"log_configuration\": {\u003cbr\u003e    \"cloud_watch_log_group_name\": \"/aws/ecs/aws-ec2\"\u003cbr\u003e  },\u003cbr\u003e  \"logging\": \"OVERRIDE\"\u003cbr\u003e}\u003c/pre\u003e | no |\n| \u003ca name=\"input_ecs_common_service_config\"\u003e\u003c/a\u003e [ecs\\_common\\_service\\_config](#input\\_ecs\\_common\\_service\\_config) | ECS service configuration:\u003cbr\u003e    - `ordered_placement_strategy` defines how tasks are placed on instances, see more [AWS docs](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-placement-strategies.html) or [Terraform docs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ecs_service)\u003cbr\u003e    - `force_new_deployment` force service redeployment\u003cbr\u003e    - `wait_for_steady_state` terraform apply waits for service to reach steady state, see more [Terraform docs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ecs_service) | \u003cpre\u003eobject({\u003cbr\u003e    ordered_placement_strategy = optional(list(object({\u003cbr\u003e      type  = string\u003cbr\u003e      field = string\u003cbr\u003e      })), [{\u003cbr\u003e      type  = \"binpack\"\u003cbr\u003e      field = \"cpu\"\u003cbr\u003e    }])\u003cbr\u003e    force_new_deployment     = optional(bool, false)\u003cbr\u003e    wait_for_steady_state    = optional(bool, true)\u003cbr\u003e    autoscaling_min_capacity = optional(number, 1)\u003cbr\u003e    autoscaling_max_capacity = optional(number, 10)\u003cbr\u003e    deployment_circuit_breaker = optional(object({\u003cbr\u003e      enable   = bool\u003cbr\u003e      rollback = bool\u003cbr\u003e      }), {\u003cbr\u003e      enable   = true\u003cbr\u003e      rollback = true\u003cbr\u003e    })\u003cbr\u003e  })\u003c/pre\u003e | `{}` | no |\n| \u003ca name=\"input_ecs_per_service_config\"\u003e\u003c/a\u003e [ecs\\_per\\_service\\_config](#input\\_ecs\\_per\\_service\\_config) | Configuration per service, overrides 'ecs\\_common\\_service\\_config'\u003cbr\u003e    Example:\u003cpre\u003e{\u003cbr\u003e      engine = {\u003cbr\u003e        image = \"registry.appmixer.com/appmixer-engine:5.2.0-nocomp\"\u003cbr\u003e        url   = \"api.ecs.appmixer.co\"\u003cbr\u003e        env = {\u003cbr\u003e          EXAMPLE_ENV = \"example\"\u003cbr\u003e        }\u003cbr\u003e        cpu          = 512\u003cbr\u003e        memory       = 1024\u003cbr\u003e        health_check = {}\u003cbr\u003e        entrypoint = [ \"node\", \"gridd.js\", \"--http\", \"--emails\" ]\u003cbr\u003e        autoscaling_min_capacity = 1\u003cbr\u003e        autoscaling_max_capacity = 10\u003cbr\u003e        force_new_deployment = true\u003cbr\u003e        wait_for_steady_state = true\u003cbr\u003e        ordered_placement_strategy = [{\u003cbr\u003e          type  = \"binpack\"\u003cbr\u003e          field = \"cpu\"\u003cbr\u003e        }]\u003cbr\u003e      }\u003cbr\u003e      quota = {...}\u003cbr\u003e      frontend = {...}\u003cbr\u003e      backoffice = {...}\u003cbr\u003e      logstash = {...}\u003cbr\u003e      }\u003cbr\u003e    }\u003c/pre\u003e | `any` | `{}` | no |\n| \u003ca name=\"input_ecs_registry_auth_data\"\u003e\u003c/a\u003e [ecs\\_registry\\_auth\\_data](#input\\_ecs\\_registry\\_auth\\_data) | Docker registry credentials, base64 encoded string | `string` | `\"\"` | no |\n| \u003ca name=\"input_elasticache\"\u003e\u003c/a\u003e [elasticache](#input\\_elasticache) | Elastic module configuration object | \u003cpre\u003eobject({\u003cbr\u003e    cluster_size               = optional(number, 1)\u003cbr\u003e    instance_type              = optional(string, \"cache.t3.micro\")\u003cbr\u003e    engine_version             = optional(string, \"6.2\")\u003cbr\u003e    family                     = optional(string, \"redis6.x\")\u003cbr\u003e    at_rest_encryption_enabled = optional(bool, true)\u003cbr\u003e    transit_encryption_enabled = optional(bool, true)\u003cbr\u003e    automatic_failover_enabled = optional(bool, false)\u003cbr\u003e    parameter = optional(list(object({\u003cbr\u003e      name  = string\u003cbr\u003e      value = string\u003cbr\u003e    })), [])\u003cbr\u003e  })\u003c/pre\u003e | `{}` | no |\n| \u003ca name=\"input_elasticsearch\"\u003e\u003c/a\u003e [elasticsearch](#input\\_elasticsearch) | Elasticsearch module configuration object | \u003cpre\u003eobject({\u003cbr\u003e    elasticsearch_version           = optional(string, \"OpenSearch_2.7\")\u003cbr\u003e    instance_type                   = optional(string, \"t3.medium.elasticsearch\")\u003cbr\u003e    instance_count                  = optional(number, 1)\u003cbr\u003e    ebs_volume_size                 = optional(number, 20)\u003cbr\u003e    encrypt_at_rest_enabled         = optional(bool, true)\u003cbr\u003e    advanced_options                = optional(map(string), null)\u003cbr\u003e    node_to_node_encryption_enabled = optional(bool, true)\u003cbr\u003e  })\u003c/pre\u003e | \u003cpre\u003e{\u003cbr\u003e  \"advanced_options\": {\u003cbr\u003e    \"rest.action.multi.allow_explicit_index\": \"true\"\u003cbr\u003e  }\u003cbr\u003e}\u003c/pre\u003e | no |\n| \u003ca name=\"input_enable_deletion_protection\"\u003e\u003c/a\u003e [enable\\_deletion\\_protection](#input\\_enable\\_deletion\\_protection) | Enable deletion protection for all managed resources, if true, resources can't be deleted if not explicitly set to false | `bool` | `true` | no |\n| \u003ca name=\"input_environment\"\u003e\u003c/a\u003e [environment](#input\\_environment) | Environment, e.g. 'prod', 'staging', 'dev', 'pre-prod', 'UAT' | `string` | `\"dev\"` | no |\n| \u003ca name=\"input_external_documentdb\"\u003e\u003c/a\u003e [external\\_documentdb](#input\\_external\\_documentdb) | Connection string to DocumentDB, if not set, DocumentDB will be automatically created | `string` | `null` | no |\n| \u003ca name=\"input_external_elasticsearch\"\u003e\u003c/a\u003e [external\\_elasticsearch](#input\\_external\\_elasticsearch) | Connection object to Elasticsearch, if not set, Elasticsearch will be automatically created | \u003cpre\u003eobject({\u003cbr\u003e    url      = string\u003cbr\u003e    username = string\u003cbr\u003e    password = string\u003cbr\u003e  })\u003c/pre\u003e | `null` | no |\n| \u003ca name=\"input_external_rabbitmq\"\u003e\u003c/a\u003e [external\\_rabbitmq](#input\\_external\\_rabbitmq) | Connection object to RabbitMQ, if not set, RabbitMQ will be automatically created | \u003cpre\u003eobject({\u003cbr\u003e    url      = string\u003cbr\u003e    username = string\u003cbr\u003e    password = string\u003cbr\u003e    port     = number\u003cbr\u003e  })\u003c/pre\u003e | `null` | no |\n| \u003ca name=\"input_external_redis\"\u003e\u003c/a\u003e [external\\_redis](#input\\_external\\_redis) | Connection string to Redis, if not set, Redis will be automatically created | `string` | `null` | no |\n| \u003ca name=\"input_external_vpc\"\u003e\u003c/a\u003e [external\\_vpc](#input\\_external\\_vpc) | VPC configuration, if not set, new VPC will be created | \u003cpre\u003eobject({\u003cbr\u003e    vpc_id             = string\u003cbr\u003e    public_subnet_ids  = list(string)\u003cbr\u003e    private_subnet_ids = list(string)\u003cbr\u003e  })\u003c/pre\u003e | `null` | no |\n| \u003ca name=\"input_init_user\"\u003e\u003c/a\u003e [init\\_user](#input\\_init\\_user) | Initial user created in appmixer. Creation through appmixer API and by setting up admin scope in documentdb directly | \u003cpre\u003eobject({\u003cbr\u003e    email             = optional(string, \"\")\u003cbr\u003e    username          = optional(string, \"\")\u003cbr\u003e    password          = optional(string, \"\")\u003cbr\u003e    max_retry_minutes = optional(number, 45)\u003cbr\u003e  })\u003c/pre\u003e | `null` | no |\n| \u003ca name=\"input_name\"\u003e\u003c/a\u003e [name](#input\\_name) | Solution name, e.g. 'appmixer' | `string` | `\"appmixer\"` | no |\n| \u003ca name=\"input_namespace\"\u003e\u003c/a\u003e [namespace](#input\\_namespace) | Namespace, which could be your organization name or abbreviation, e.g. 'eg' or 'cp' | `string` | `\"cio\"` | no |\n| \u003ca name=\"input_rabbitmq\"\u003e\u003c/a\u003e [rabbitmq](#input\\_rabbitmq) | RabbitMQ module configuration object | \u003cpre\u003eobject({\u003cbr\u003e    auto_minor_version_upgrade = optional(bool, true)\u003cbr\u003e    deployment_mode            = optional(string, \"SINGLE_INSTANCE\")\u003cbr\u003e    engine_version             = optional(string, \"3.8.34\")\u003cbr\u003e    host_instance_type         = optional(string, \"mq.t3.micro\")\u003cbr\u003e    audit_log_enabled          = optional(bool, false)\u003cbr\u003e    general_log_enabled        = optional(bool, true)\u003cbr\u003e    encryption_enabled         = optional(bool, true)\u003cbr\u003e    use_aws_owned_key          = optional(bool, false)\u003cbr\u003e    publicly_accessible        = optional(bool, false)\u003cbr\u003e  })\u003c/pre\u003e | `{}` | no |\n| \u003ca name=\"input_s3_config\"\u003e\u003c/a\u003e [s3\\_config](#input\\_s3\\_config) | Configuration for S3 bucket | \u003cpre\u003eobject({\u003cbr\u003e    versioning_enabled = optional(bool, false)\u003cbr\u003e    logging            = optional(list(object({ bucket_name = string, prefix = string })), [])\u003cbr\u003e  })\u003c/pre\u003e | `{}` | no |\n| \u003ca name=\"input_stage\"\u003e\u003c/a\u003e [stage](#input\\_stage) | Stage, e.g. 'prod', 'staging', 'dev' | `string` | `\"\"` | no |\n| \u003ca name=\"input_tags\"\u003e\u003c/a\u003e [tags](#input\\_tags) | Additional tags (e.g. `map('BusinessUnit','XYZ')` | `map(string)` | `{}` | no |\n| \u003ca name=\"input_vpc_config\"\u003e\u003c/a\u003e [vpc\\_config](#input\\_vpc\\_config) | VPC configuration, ignored if `external_vpc` is set | \u003cpre\u003eobject({\u003cbr\u003e    ipv4_primary_cidr_block = string\u003cbr\u003e    availability_zones      = list(string)\u003cbr\u003e  })\u003c/pre\u003e | \u003cpre\u003e{\u003cbr\u003e  \"availability_zones\": [\u003cbr\u003e    \"eu-central-1a\",\u003cbr\u003e    \"eu-central-1b\",\u003cbr\u003e    \"eu-central-1c\"\u003cbr\u003e  ],\u003cbr\u003e  \"ipv4_primary_cidr_block\": \"10.0.0.0/16\"\u003cbr\u003e}\u003c/pre\u003e | no |\n| \u003ca name=\"input_zone_id\"\u003e\u003c/a\u003e [zone\\_id](#input\\_zone\\_id) | Route53 DNS zone ID, if not set AWS route53 will be not used | `string` | `null` | no |\n\n## Outputs\n\n| Name | Description |\n|------|-------------|\n| \u003ca name=\"output_alb_dns_name\"\u003e\u003c/a\u003e [alb\\_dns\\_name](#output\\_alb\\_dns\\_name) | DNS name of the ALB |\n| \u003ca name=\"output_managed_services\"\u003e\u003c/a\u003e [managed\\_services](#output\\_managed\\_services) | Managed services configuration containing endpoints and name of SSM parameters with credentials |\n| \u003ca name=\"output_services_urls\"\u003e\u003c/a\u003e [services\\_urls](#output\\_services\\_urls) | URLs of the running services |\n| \u003ca name=\"output_vpc_config\"\u003e\u003c/a\u003e [vpc\\_config](#output\\_vpc\\_config) | VPC configuration contaning VPC ID, CIDR block and subnets |\n\u003c!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK --\u003e\n\n## Contributing and reporting issues\n\nFeel free to create an issue in this repository if you have questions, suggestions or feature requests.\n\n### Validation, linters and pull-requests\n\nWe want to provide high quality code and modules. For this reason we are using\nseveral [pre-commit hooks](.pre-commit-config.yaml) and\n[GitHub Actions workflows](.github/workflows/). A pull-request to the\nmain branch will trigger these validations and lints automatically. Please\ncheck your code before you will create pull-requests. See\n[pre-commit documentation](https://pre-commit.com/) and\n[GitHub Actions documentation](https://docs.github.com/en/actions) for further\ndetails.\n\n## License\n\n[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)\n\nSee [LICENSE](LICENSE) for full details.\n\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      https://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclientio%2Fappmixer-module-aws","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fclientio%2Fappmixer-module-aws","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclientio%2Fappmixer-module-aws/lists"}