From a28ed4e0da0e4a04114eb103bf3edb52662216d9 Mon Sep 17 00:00:00 2001 From: stelcheck Date: Thu, 15 Nov 2018 15:50:26 +0900 Subject: [PATCH] Portainer, email notifs, ldap ssp - Detect terraform usage, use dynamic inventory - AWS template: use SES for emails - Barebone, local template updates - LDAP: self-service email reset - Grafana: always use SSL - Grafana: email config - Portainer: new role - Fix: swarm auth health check --- buildconfig.yml | 4 +- docker-image/Dockerfile | 16 ++++ .../roles/grafana/templates/grafana.ini.j2 | 12 +-- .../grafana/templates/grafana_stack.yml.j2 | 1 + .../ansible/roles/openldap/meta/main.yml | 6 ++ .../ansible/roles/openldap/tasks/setup.yml | 25 ++++++ .../ansible/roles/portainer/defaults/main.yml | 21 +++++ .../ansible/roles/portainer/tasks/main.yml | 43 ++++++++++ .../ansible/roles/portainer/tasks/server.yml | 60 ++++++++++++++ .../templates/portainer_stack.yml.j2 | 37 +++++++++ .../portainer/templates/registry.json.j2 | 7 ++ .../portainer/templates/settings.json.j2 | 38 +++++++++ .../roles/swarm/templates/swarm_auth.sh.j2 | 2 +- docker-image/scripts/docker_entrypoint.sh | 6 ++ docker-image/scripts/pylib/__init__.py | 2 + .../templates/aws/ansible/group_vars/all | 3 +- .../templates/aws/ansible/playbook.yml | 8 ++ docker-image/templates/aws/terraform.tfvars | 4 + .../templates/aws/terraform/ansible.tf | 81 +++++++++++++++++++ docker-image/templates/aws/terraform/aws.tf | 5 ++ docker-image/templates/aws/terraform/dns.tf | 43 ++++++++++ docker-image/templates/aws/terraform/email.tf | 45 +++++++++++ .../aws/terraform/security_groups.tf | 8 ++ .../templates/aws/terraform/variables.tf | 4 + .../templates/bare/ansible/group_vars/all | 6 ++ .../templates/bare/ansible/playbook.yml | 8 ++ .../templates/local/ansible/group_vars/all | 6 ++ .../templates/local/ansible/playbook.yml | 8 ++ 28 files changed, 498 insertions(+), 11 deletions(-) create mode 100644 docker-image/ansible/roles/portainer/defaults/main.yml create mode 100644 docker-image/ansible/roles/portainer/tasks/main.yml create mode 100644 docker-image/ansible/roles/portainer/tasks/server.yml create mode 100644 docker-image/ansible/roles/portainer/templates/portainer_stack.yml.j2 create mode 100644 docker-image/ansible/roles/portainer/templates/registry.json.j2 create mode 100644 docker-image/ansible/roles/portainer/templates/settings.json.j2 create mode 100644 docker-image/templates/aws/terraform/ansible.tf create mode 100644 docker-image/templates/aws/terraform/dns.tf create mode 100644 docker-image/templates/aws/terraform/email.tf diff --git a/buildconfig.yml b/buildconfig.yml index e77e22a..ddb437f 100644 --- a/buildconfig.yml +++ b/buildconfig.yml @@ -41,7 +41,7 @@ binary: name: "dawn" # The current version of the binary - version: "0.12.10" + version: "0.14.0" # (Optional) URLs to call when attempting auto-update. # Defaults: @@ -78,7 +78,7 @@ image: name: dawn # Current image version - version: "0.12.10" + version: "0.14.0" # Root folder where most files will be uploaded or mounted root_folder: /dawn diff --git a/docker-image/Dockerfile b/docker-image/Dockerfile index 083c7ce..dcb9886 100644 --- a/docker-image/Dockerfile +++ b/docker-image/Dockerfile @@ -72,6 +72,22 @@ RUN wget -q https://releases.hashicorp.com/terraform/${terraform_version}/terraf && unzip -q /tmp/terraform.zip \ && rm /tmp/terraform.zip +# Ansible inventory using Terraform state +RUN wget https://raw.githubusercontent.com/nbering/terraform-inventory/master/terraform.py \ + -O /etc/ansible/terraform.py \ + && chmod 755 /etc/ansible/terraform.py + +# Ansible provider +ARG terraform_ansible_repo=https://github.com/nbering/terraform-provider-ansible +ARG terraform_ansible_version=v0.0.4 + +RUN cd /tmp \ + && export zip="terraform-provider-ansible-linux_386.zip" \ + && wget ${terraform_ansible_repo}/releases/download/${terraform_ansible_version}/${zip} \ + && unzip ${zip} \ + && mv linux_386/terraform-provider-ansible_${terraform_ansible_version} /usr/bin/terraform-provider-ansible \ + && rm ${zip} + # Install Vault RUN wget -q https://releases.hashicorp.com/vault/${vault_version}/vault_${vault_version}_linux_amd64.zip \ -O /tmp/vault.zip \ diff --git a/docker-image/ansible/roles/grafana/templates/grafana.ini.j2 b/docker-image/ansible/roles/grafana/templates/grafana.ini.j2 index f6ff417..6c0a804 100644 --- a/docker-image/ansible/roles/grafana/templates/grafana.ini.j2 +++ b/docker-image/ansible/roles/grafana/templates/grafana.ini.j2 @@ -273,16 +273,16 @@ config_file = /etc/grafana/ldap.toml #################################### SMTP / Emailing ########################## [smtp] -;enabled = false -;host = localhost:25 -;user = +enabled = true +host = {{ smtp_hostname }}:{{ smtp_port }} +user = {{ smtp_username }} # If the password contains # or ; you have to wrap it with trippel quotes. Ex """#password;""" -;password = +password = {{ smtp_password }} ;cert_file = ;key_file = ;skip_verify = false -;from_address = admin@grafana.localhost -;from_name = Grafana +from_address = grafana@{{ local_domain_name }} +from_name = Grafana:{{ local_domain_name }} [emails] ;welcome_email_on_sign_up = false diff --git a/docker-image/ansible/roles/grafana/templates/grafana_stack.yml.j2 b/docker-image/ansible/roles/grafana/templates/grafana_stack.yml.j2 index 3bf6d33..cb06751 100644 --- a/docker-image/ansible/roles/grafana/templates/grafana_stack.yml.j2 +++ b/docker-image/ansible/roles/grafana/templates/grafana_stack.yml.j2 @@ -51,5 +51,6 @@ services: traefik.port: 3000 traefik.frontend.rule: "Host:grafana.{{ local_domain_name }}" traefik.frontend.whitelist.sourceRange: "{{ grafana_whitelist }}" + traefik.frontend.headers.SSLRedirect: "true" traefik.backend.loadbalancer.stickiness: "true" traefik.docker.network: traefik_net diff --git a/docker-image/ansible/roles/openldap/meta/main.yml b/docker-image/ansible/roles/openldap/meta/main.yml index 9b00036..46e1562 100644 --- a/docker-image/ansible/roles/openldap/meta/main.yml +++ b/docker-image/ansible/roles/openldap/meta/main.yml @@ -11,3 +11,9 @@ dependencies: service_port: 18080 service_ip: "{{ group_ipv4.control[0] }}" service_whitelist: "{{ phpldapadmin_whitelist }}" + - role: traefik-expose + service_name: ldap-ssp + service_scheme: http + service_port: 28080 + service_ip: "{{ group_ipv4.control[0] }}" + service_whitelist: "{{ phpldapadmin_whitelist }}" diff --git a/docker-image/ansible/roles/openldap/tasks/setup.yml b/docker-image/ansible/roles/openldap/tasks/setup.yml index 55b3aca..c95aac3 100644 --- a/docker-image/ansible/roles/openldap/tasks/setup.yml +++ b/docker-image/ansible/roles/openldap/tasks/setup.yml @@ -68,6 +68,31 @@ PHPLDAPADMIN_HTTPS: "false" PHPLDAPADMIN_TRUST_PROXY_SSL: "true" +- name: "Start self-service password reset" + docker_container: + name: ldap-ssp + image: tiredofit/self-service-password + restart_policy: always + published_ports: + - "28080:80" + links: + - "openldap:ldap" + env: + SECRETEKEY: "all your base are belong to us" + LDAP_SERVER: "ldap://{{ ldap_server }}:{{ ldap_server_port }}" + LDAP_BINDDN: "{{ ldap_admin_user }}" + LDAP_BINDPASS: "{{ ldap_admin_password }}" + LDAP_BASE_SEARCH: "{{ ldap_dc }}" + PASSWORD_MIN_LENGTH: 8 + MAIL_FROM: "ldap@{{ local_domain_name }}" + MAIL_FROM_NAME: "LDAP:{{ local_domain_name }}" + NOTIFY_ON_CHANGE: true + SMTP_HOST: "{{ smtp_hostname }}" + SMTP_PORT: "{{ smtp_port }}" + SMTP_AUTH_ON: "true" + SMTP_USER: "{{ smtp_username }}" + SMTP_PASS: "{{ smtp_password }}" + - name: "Create the different organizational units" ldap_entry: server_uri: "ldap://{{ ldap_server }}:{{ ldap_server_port }}/" diff --git a/docker-image/ansible/roles/portainer/defaults/main.yml b/docker-image/ansible/roles/portainer/defaults/main.yml new file mode 100644 index 0000000..b75dc85 --- /dev/null +++ b/docker-image/ansible/roles/portainer/defaults/main.yml @@ -0,0 +1,21 @@ +portainer_version: "1.19.2" + +portainer_endpoint: "portainer.{{ local_domain_name }}" +portainer_whitelist: "0.0.0.0/0" +portainer_stack: "portainer" +portainer_stack_file: "/opt/dawn/portainer.yml" + +portainer_admin_username: "admin" +portainer_admin_password: "RkhGg!,n4JM.SqcTV>4r@sEM" + +portainer_allow_bindmounts_users: true +portainer_allow_privileged_users: true + +docker_client_key_file: /etc/ssl/certs/docker/client.key.pem +docker_client_cert_file: /etc/ssl/certs/docker/client.cert.pem +docker_client_ca_file: /etc/ssl/certs/docker/client.ca.pem + +ldap_server: "{{ group_ipv4.control[0] }}" +ldap_server_port: 389 +ldap_dc: "dc={{ local_domain_name.split('.') | join(',dc=') }}" +ldap_admin_user: "cn=admin,{{ ldap_dc }}" diff --git a/docker-image/ansible/roles/portainer/tasks/main.yml b/docker-image/ansible/roles/portainer/tasks/main.yml new file mode 100644 index 0000000..f74667c --- /dev/null +++ b/docker-image/ansible/roles/portainer/tasks/main.yml @@ -0,0 +1,43 @@ +- import_tasks: server.yml + when: groups['control'][0] == inventory_hostname + +- name: "Generate authentication token" + uri: + url: "https://{{ portainer_endpoint }}/api/auth" + method: POST + return_content: yes + body_format: json + body: '{ "Username":"{{ portainer_admin_username }}", "Password":"{{ portainer_admin_password }}"}' + register: auth_token + +- name: "Check if endpoint is registered" + warn: false + shell: | + curl "https://{{ portainer_endpoint }}/api/endpoints" \ + -XGET \ + -H "Authorization: {{ (auth_token.content|from_json).jwt }}" + register: portainer_endpoints + changed_when: > + portainer_endpoints.stdout + |from_json + |selectattr("Name", "equalto", inventory_hostname) + |list + |length == 0 + +- name: "Register endpoint" + warn: false + shell: | + curl "https://{{ portainer_endpoint }}/api/endpoints" \ + -XPOST \ + -H "Authorization: {{ (auth_token.content|from_json).jwt }}" \ + -F "Name={{ inventory_hostname }}" \ + -F "EndpointType=1" \ + -F "URL=tcp://{{ private_ipv4 + ":2376" }}" \ + -F "PublicURL={{ private_ipv4 + ":2376" }}" \ + -F "TLS=true" \ + -F "TLSSkipVerify=false" \ + -F "TLSSkipClientVerify=false" \ + -F "TLSCACertFile=@{{ docker_client_ca_file }}" \ + -F "TLSCertFile=@{{ docker_client_cert_file }}" \ + -F "TLSKeyFile=@{{ docker_client_key_file }}" + when: portainer_endpoints.changed|bool diff --git a/docker-image/ansible/roles/portainer/tasks/server.yml b/docker-image/ansible/roles/portainer/tasks/server.yml new file mode 100644 index 0000000..efe152f --- /dev/null +++ b/docker-image/ansible/roles/portainer/tasks/server.yml @@ -0,0 +1,60 @@ +- name: "Create portainer stack file" + template: + dest: "{{ portainer_stack_file }}" + src: "portainer_stack.yml.j2" + register: portainer_stack_file_status + +- name: "Check if portainer is running" + shell: "docker stack ps {{ portainer_stack }}" + changed_when: portainer_running_state.rc != 0 + ignore_errors: yes + register: portainer_running_state + +- name: "Start portainer on the cluster" + when: > + portainer_running_state.changed|bool + or portainer_stack_file_status.changed|bool + shell: "docker stack deploy -c '{{ portainer_stack_file }}' {{ portainer_stack }}" + +- name: "Check if we will need to create admin user" + uri: + url: "https://{{ portainer_endpoint }}/api/auth" + method: POST + return_content: yes + body_format: json + body: '{ "Username":"{{ portainer_admin_username }}", "Password":"{{ portainer_admin_password }}"}' + changed_when: portainer_create_user|failed + register: portainer_create_user + ignore_errors: true + +- name: "Configure admin user password" + uri: + url: "https://{{ portainer_endpoint }}/api/users/admin/init" + method: POST + return_content: yes + body_format: json + body: '{ "Username":"{{ portainer_admin_username }}", "Password":"{{ portainer_admin_password }}"}' + when: portainer_create_user.changed|bool + register: portainer_user_created + retries: 10 + delay: 10 + until: portainer_user_created|success + +- name: "Generate authentication token" + uri: + url: "https://{{ portainer_endpoint }}/api/auth" + method: POST + return_content: yes + body_format: json + body: '{ "Username":"{{ portainer_admin_username }}", "Password":"{{ portainer_admin_password }}"}' + register: auth_token + +- name: "Configure portainer settings" + uri: + url: "https://{{ portainer_endpoint }}/api/settings" + method: PUT + return_content: yes + headers: + Authorization: "{{ (auth_token.content|from_json).jwt }}" + body_format: json + body: "{{ lookup('template','settings.json.j2') }}" diff --git a/docker-image/ansible/roles/portainer/templates/portainer_stack.yml.j2 b/docker-image/ansible/roles/portainer/templates/portainer_stack.yml.j2 new file mode 100644 index 0000000..26fd2c6 --- /dev/null +++ b/docker-image/ansible/roles/portainer/templates/portainer_stack.yml.j2 @@ -0,0 +1,37 @@ +version: '3' + +volumes: + portainer_data: + +networks: + prometheus: + external: + name: prometheus_net + traefik: + external: + name: traefik_net + +services: + portainer: + image: portainer/portainer:{{ portainer_version }} + command: -H unix:///var/run/docker.sock + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - portainer_data:/data + networks: + - prometheus + - traefik + deploy: + replicas: 1 + restart_policy: + condition: on-failure + placement: + constraints: + - engine.labels.dawn.node.type == control + labels: + traefik.port: 9000 + traefik.frontend.rule: "Host: {{ portainer_endpoint }}" + traefik.frontend.whitelist.sourceRange: "{{ portainer_whitelist }}" + traefik.frontend.headers.SSLRedirect: "true" + traefik.backend.loadbalancer.stickiness: "true" + traefik.docker.network: traefik_net diff --git a/docker-image/ansible/roles/portainer/templates/registry.json.j2 b/docker-image/ansible/roles/portainer/templates/registry.json.j2 new file mode 100644 index 0000000..0fdecdd --- /dev/null +++ b/docker-image/ansible/roles/portainer/templates/registry.json.j2 @@ -0,0 +1,7 @@ +{ + "Name": "Dawn Registry", + "URL": "{{ registry_url }}:{{ registry_port }}", + "Authentication": true, + "Username": "{{ registry_username }}", + "Password": "{{ registry_password }}" +} diff --git a/docker-image/ansible/roles/portainer/templates/settings.json.j2 b/docker-image/ansible/roles/portainer/templates/settings.json.j2 new file mode 100644 index 0000000..46cb449 --- /dev/null +++ b/docker-image/ansible/roles/portainer/templates/settings.json.j2 @@ -0,0 +1,38 @@ +{ + {% if portainer_templates_url is defined %} + "TemplatesURL": "{{ portainer_templates_url }}", + {% endif %} + {% if portainer_company_logo_url is defined %} + "LogoURL": "{{ portainer_company_logo_url }}", + {% endif %} + "DisplayDonationHeader": false, + "DisplayExternalContributors": true, + "AuthenticationMethod": 2, + "LDAPSettings": { + "ReaderDN": "{{ ldap_admin_user }}", + "Password": "{{ ldap_admin_password }}", + "URL": "{{ ldap_server }}:{{ ldap_server_port }}", + "TLSConfig": { + "TLS": false, + "TLSSkipVerify": true + }, + "StartTLS": false, + "SearchSettings": [ + { + "BaseDN": "ou=users,{{ ldap_dc }}", + "Filter": "", + "UserNameAttribute": "uid" + } + ], + "GroupSearchSettings": [ + { + "GroupBaseDN": "ou=groups,{{ ldap_dc }}", + "GroupFilter": "", + "GroupAttribute": "cn" + } + ], + "AutoCreateUsers": true + }, + "AllowBindMountsForRegularUsers": {{ portainer_allow_bindmounts_users }}, + "AllowPrivilegedModeForRegularUsers": {{ portainer_allow_privileged_users }} +} diff --git a/docker-image/ansible/roles/swarm/templates/swarm_auth.sh.j2 b/docker-image/ansible/roles/swarm/templates/swarm_auth.sh.j2 index 7be8316..920be8d 100644 --- a/docker-image/ansible/roles/swarm/templates/swarm_auth.sh.j2 +++ b/docker-image/ansible/roles/swarm/templates/swarm_auth.sh.j2 @@ -38,7 +38,7 @@ chmod -R 0640 "${DOCKER_CERT_PATH}" # health check - if null, the received data differs from expected if - ! grep -sr null "${DOCKER_CERT_PATH}" + grep -sr null "${DOCKER_CERT_PATH}" then echo "!!! Certificate creation failed:" echo "${DOCKER_CERT}" diff --git a/docker-image/scripts/docker_entrypoint.sh b/docker-image/scripts/docker_entrypoint.sh index 33d0d4d..4812f08 100755 --- a/docker-image/scripts/docker_entrypoint.sh +++ b/docker-image/scripts/docker_entrypoint.sh @@ -65,6 +65,12 @@ fi popd > /dev/null +if + [ -d "${PROJECT_ENVIRONMENT_FILES_PATH}/terraform" ] +then + export ANSIBLE_INVENTORY="/etc/ansible/terraform.py" +fi + # We finally downgrade the user and run the # command. The reason for this is twofold: # diff --git a/docker-image/scripts/pylib/__init__.py b/docker-image/scripts/pylib/__init__.py index 682cd17..0baae03 100644 --- a/docker-image/scripts/pylib/__init__.py +++ b/docker-image/scripts/pylib/__init__.py @@ -80,11 +80,13 @@ # display additional information motd_section "Web UI" + motd_section_entry "Portainer" "https://portainer.{{ local_domain_name }}/" motd_section_entry "Kibana" "https://kibana.{{ local_domain_name }}/" motd_section_entry "Grafana" "https://grafana.{{ local_domain_name }}/" motd_section_entry "Prometheus" "https://prometheus.{{ local_domain_name }}" motd_section_entry "Traefik" "https://{{ local_domain_name }}:8080" motd_section_entry "LDAP Admin" "https://ldap-admin.{{ local_domain_name }}" + motd_section_entry "Pass. reset" "https://ldap-ssp.{{ local_domain_name }}" motd_section_entry "Teleport" "https://teleport.{{ local_domain_name }}" motd_section_end diff --git a/docker-image/templates/aws/ansible/group_vars/all b/docker-image/templates/aws/ansible/group_vars/all index cafa915..148113e 100644 --- a/docker-image/templates/aws/ansible/group_vars/all +++ b/docker-image/templates/aws/ansible/group_vars/all @@ -2,8 +2,7 @@ # do it in your inventory [all:vars] section or use --extra-vars, it is used by # docker containers and various elements of dawn to find which machines is where # via consul -# local_domain_name: local.dawn -# local_domain_dc: in +local_domain_dc: in local_domain_full: "{{ local_domain_dc }}.{{ local_domain_name }}" # Local storage is used to put your client vault certificates and vault config diff --git a/docker-image/templates/aws/ansible/playbook.yml b/docker-image/templates/aws/ansible/playbook.yml index 5e2c3e7..e022904 100644 --- a/docker-image/templates/aws/ansible/playbook.yml +++ b/docker-image/templates/aws/ansible/playbook.yml @@ -94,5 +94,13 @@ - role: grafana tags: [ 'group:monitor', 'role:grafana', 'type:monitoring' ] +# Deploy portainer +- hosts: all + become: true + gather_facts: yes + roles: + - role: portainer + tags: [ 'role:portainer' ] + # Fetch client certificates - include: /dawn/ansible/playbooks/client_certs.yml diff --git a/docker-image/templates/aws/terraform.tfvars b/docker-image/templates/aws/terraform.tfvars index c9220ec..e5c78b9 100644 --- a/docker-image/templates/aws/terraform.tfvars +++ b/docker-image/templates/aws/terraform.tfvars @@ -1,9 +1,13 @@ # Region region = "us-west-1" +ses_region = "us-west-2" # Availability zone availability_zone = "us-west-1b" +# Domain name for the environment +domain = "" + # CIDR Block to assign to the VPC's network cidr_blocks = { vpc = "172.24.0.0/16" diff --git a/docker-image/templates/aws/terraform/ansible.tf b/docker-image/templates/aws/terraform/ansible.tf new file mode 100644 index 0000000..03e511c --- /dev/null +++ b/docker-image/templates/aws/terraform/ansible.tf @@ -0,0 +1,81 @@ +resource "ansible_group" "all" { + inventory_group_name = "all" + children = ["docker"] + vars { + ansible_ssh_private_key_file = "/home/dawn/.ssh/deploy" + ansible_host_key_checking = "false" + local_domain_name = "${var.domain}" + smtp_hostname = "email-smtp.${var.ses_region}.amazonaws.com" + smtp_port = "587" + smtp_username = "${aws_iam_access_key.smtp.id}" + smtp_password = "${aws_iam_access_key.smtp.ses_smtp_password}" + } +} + +resource "ansible_group" "ssh-proxied" { + inventory_group_name = "ssh-proxied" + + vars { + ansible_ssh_extra_args = "-o ProxyCommand='ssh -l ${var.nodes["edge_ami_user"]} -i ~/.ssh/deploy -W %h:%p -q ${aws_eip.edge.public_ip}'" + } +} + +resource "ansible_group" "docker" { + inventory_group_name = "docker" + children = ["swarm"] +} + +resource "ansible_group" "swarm" { + inventory_group_name = "swarm" + children = ["consul", "monitor", "control", "edge", "worker"] +} + +resource "ansible_group" "monitor" { + inventory_group_name = "monitor" +} + +resource "ansible_group" "control" { + inventory_group_name = "control" +} + +resource "ansible_group" "edge" { + inventory_group_name = "edge" +} + +resource "ansible_host" "edge" { + count = "${var.nodes["edge_count"]}" + inventory_hostname = "${var.project_name}-${var.project_environment}-edge-${count.index}" + groups = ["edge"] + vars { + ansible_user = "${var.nodes["edge_ami_user"]}" + ansible_host = "${element(aws_eip.edge.*.public_ip, count.index)}" + } +} + +resource "ansible_host" "control_and_monitor" { + count = "${var.nodes["control_count"]}" + inventory_hostname = "${var.project_name}-${var.project_environment}-control-${count.index}" + groups = ["control", "monitor", "ssh-proxied"] + vars { + ansible_user = "${var.nodes["control_ami_user"]}" + ansible_host = "${element(aws_instance.control.*.private_ip, count.index)}" + + // The following variables will be used by gitlab-runner + mysql_host = "${aws_rds_cluster.aurora.endpoint}" + mysql_db = "${aws_rds_cluster.aurora.database_name}" + mysql_user = "${aws_rds_cluster.aurora.master_username}" + mysql_pass = "${aws_rds_cluster.aurora.master_password}" + redis_host = "${aws_elasticache_cluster.redis.cache_nodes.0.address}" + + } +} + +resource "ansible_host" "worker" { + count = "${var.nodes["worker_count"]}" + inventory_hostname = "${var.project_name}-${var.project_environment}-worker-${count.index}" + groups = ["worker", "ssh-proxied"] + vars { + ansible_user = "${var.nodes["worker_ami_user"]}" + ansible_host = "${element(aws_instance.worker.*.private_ip, count.index)}" + } +} diff --git a/docker-image/templates/aws/terraform/aws.tf b/docker-image/templates/aws/terraform/aws.tf index 634e1f6..b2c8ec6 100644 --- a/docker-image/templates/aws/terraform/aws.tf +++ b/docker-image/templates/aws/terraform/aws.tf @@ -1,4 +1,9 @@ # Provider definition +provider "aws" { + region = "${var.ses_region}" + alias = "ses_region" +} + provider "aws" { region = "${var.region}" } diff --git a/docker-image/templates/aws/terraform/dns.tf b/docker-image/templates/aws/terraform/dns.tf new file mode 100644 index 0000000..549cab5 --- /dev/null +++ b/docker-image/templates/aws/terraform/dns.tf @@ -0,0 +1,43 @@ +data "aws_route53_zone" "main" { + name = "${var.domain}" +} + +resource "aws_route53_record" "main" { + zone_id = "${data.aws_route53_zone.main.zone_id}" + name = "${var.domain}" + type = "A" + ttl = "300" + + records = [ + "${aws_eip.edge.*.public_ip}" + ] +} + +resource "aws_route53_record" "wildcard" { + zone_id = "${data.aws_route53_zone.main.zone_id}" + name = "*.${var.domain}" + type = "A" + ttl = "300" + + records = [ + "${aws_eip.edge.*.public_ip}" + ] +} + +resource "aws_route53_record" "email" { + zone_id = "${data.aws_route53_zone.main.zone_id}" + name = "_amazonses.${var.domain}" + type = "TXT" + ttl = "600" + records = ["${aws_ses_domain_identity.smtp.verification_token}"] +} + +resource "aws_route53_record" "email_dkim" { + count = 3 + zone_id = "${data.aws_route53_zone.main.zone_id}" + + name = "${element(aws_ses_domain_dkim.smtp.dkim_tokens, count.index)}._domainkey.${var.domain}" + type = "CNAME" + ttl = "600" + records = ["${element(aws_ses_domain_dkim.smtp.dkim_tokens, count.index)}.dkim.amazonses.com"] +} diff --git a/docker-image/templates/aws/terraform/email.tf b/docker-image/templates/aws/terraform/email.tf new file mode 100644 index 0000000..520bf8e --- /dev/null +++ b/docker-image/templates/aws/terraform/email.tf @@ -0,0 +1,45 @@ +resource "aws_iam_user" "smtp" { + provider = "aws.ses_region" + name = "mailer" +} + +resource "aws_iam_user_policy" "smtp_send" { + name = "test" + user = "${aws_iam_user.smtp.name}" + + policy = <