Образовательный проект «SnakeProject» Михаила Козлова

Навигация

⇒ FreeBSD and Nix ⇐

CISCO

Voice(Asterisk\Cisco)

Microsoft

Powershell

Python

SQL\T-SQL

Общая

WEB Разработка

ORACLE SQL \ JAVA

Мото

Стрельба, пневматика, оружие

Саморазвитие и психология


Terraform + ansible nginx + lets encrypt


Terraform + ansible nginx + lets encrypt
 
Мы уже делали несколько статей по созданию vps с помощью terraform
Далее создавалась запись в dns, ставился nginx
Тут небольшое продолжение, прикрутим автоматические lets encrypt серты
hosts.yml создается на этапе терраформа, внося ip созданной машины
Далее домен, ip уже используются в ansible
Плейбуком отрабатываем роли установки инфраструктуры для nginx и сертов
 
 
Terraform
 
# cat terraform.tfvars
do_token="111"
local_ssh_key_path="~/.ssh/id_rsa.pub"
email="user_at_domain_ru"
aws_access_key = "222"
aws_secret_key = "333"
 
# cat variables.tf
variable "do_token" {}
variable "aws_access_key" {}
variable "aws_secret_key" {}
variable "aws_region" {
  default = "eu-west-1"
}
variable "local_ssh_public_key" {
    default     = "~/.ssh/id_rsa.pub"
}
variable "local_ssh_private_key" {
    default     = "~/.ssh/id_rsa"
}
variable "devs" {
  description = "Settings"
  type        = map(any)
  default     = {
    your_login  = "myname",
    general_domain = "domain.ru"
  }
}
 
# cat vars.tmpl
---
# vars file for nginx
key: ~/.ssh/id_rsa
worker_connections: 512
days: ['1', '2', '3', '4', '5', '6', '7']
nginx_vhosts:
    - {servername: "${domain}", documentroot: "/www/${domain}"}
dehydrated_dirs:
    - {dirname: "/etc/dehydrated"}
    - {dirname: "/var/lib/dehydrated"}
    - {dirname: "/var/lib/dehydratedi/acme-challenges"}
domain_list_file_path: "/etc/dehydrated/domains.txt"
 
# cat hosts.tmpl
all:
  hosts:
   vps:
     ansible_ssh_host: ${ipv4_address}
     ansible_ssh_private_file: ~/.ssh/id_rsa
 
# cat provider.tf
terraform {
  required_providers {
    digitalocean = {
      source = "digitalocean/digitalocean"
      version = "~> 2.0"
    }
  }
}
provider "digitalocean" {
  token = var.do_token
}
provider "aws" {
    access_key  = var.aws_access_key
    secret_key  = var.aws_secret_key
    region = var.aws_region
}
 
# cat resources.tf
resource "digitalocean_volume" "tv1" {
  region                  = "nyc1"
  name                    = "tv1"
  size                    = 1
  initial_filesystem_type = "ext4"
}
 
resource "digitalocean_ssh_key" "local_ssh_pkey" {
  name       = "local_ssh_public_key"
  public_key = file(var.local_ssh_public_key)
}
 
resource "digitalocean_droplet" "foobar" {
  name   = "test-vps"
  size   = "s-1vcpu-1gb"
  image  = "ubuntu-20-04-x64"
  region = "nyc1"
  ssh_keys   = [digitalocean_ssh_key.local_ssh_pkey.id]
  volume_ids = [digitalocean_volume.tv1.id]
}
 
locals {
  vps_ip = digitalocean_droplet.foobar.ipv4_address
}
 
data "aws_route53_zone" "zone" {
  name = var.devs.general_domain
}
 
resource "aws_route53_record" "record" {
  zone_id = data.aws_route53_zone.zone.id
  name    = var.devs.your_login
  allow_overwrite = true
  type    = "A"
  ttl     = "300"
  records = [local.vps_ip]
}
 
resource "local_file" "hosts" {
  filename = "${path.module}/hosts.yml"
  content = templatefile("${path.module}/hosts.tmpl",
    {
      ipv4_address = digitalocean_droplet.foobar.ipv4_address
    }
  )
}
 
resource "local_file" "vars" {
  filename = "${path.module}/roles/nginx/vars/main.yml"
  content = templatefile("${path.module}/vars.tmpl",
    {
      domain = "${var.devs.your_login}.${var.devs.general_domain}"
    }
  )
}
 
# terraform init
# terraform plan
# terraform apply
 
Ansible
 
# cat config
BASEDIR=/var/lib/dehydrated
WELLKNOWN="${BASEDIR}/acme-challenges"
DOMAINS_TXT="/etc/dehydrated/domains.txt"
 
# cat ansible.cfg
[defaults]
host_key_checking=false
inventory=./hosts.yml
 
# cat playbook.yml
- hosts:
  - vps
  become: true
  roles:
    - role: nginx
      tags:
        - install_nginx
    - role: certs
      tags:
        - get_certs
 
# cat roles\nginx\templates\index.j2
Hello from {{ item.servername }}
Days of the week:
{% for item in days%}
{{ loop.index }}  {{ item|upper }}
{% endfor %}
 
# cat roles\nginx\templates\nginx.j2
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
 
events {
worker_connections {{ worker_connections }};
}
 
http {
gzip on;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
 
include /etc/nginx/mime.types;
default_type application/octet-stream;
 
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
 
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
 
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
 
# cat roles\nginx\templates\vhost.j2
server {
  listen 80;
  server_name {{ item.servername }};
  location ^~ /.well-known/acme-challenge {
    alias /var/lib/dehydrated/acme-challenges;
  }
  location / {
    return 301 https://$host$request_uri;
  }
}
#server {
#  listen 443 ssl;
#  root {{ item.documentroot }}/html/;
#  index index.htm;
#  server_name {{ item.servername }};
#  ssl_certificate     /var/lib/dehydrated/certs/{{ item.servername }}/fullchain.pem;
#  ssl_certificate_key /var/lib/dehydrated/certs/{{ item.servername }}/privkey.pem;
#  ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
#  ssl_ciphers         HIGH:!aNULL:!MD5;
#  location ^~ /.well-known/acme-challenge {
#    alias /var/lib/dehydrated/acme-challenges;
#  }
#  location / {
#    try_files $uri $uri/ =404;
#  }
#}
 
# cat roles\nginx\handlers\main.yml
---
# handlers file for nginx
- name: reloaded nginx
  service:
    name: nginx
    state: reloaded
 
# cat roles\nginx\tasks\main.yml
---
# tasks file for nginx
- name: Install web server NGINX
  apt:
    name: nginx
    state: present
    update_cache: yes
- name: Enable and ensure is started NGINX service
  service:
    name: nginx
    enabled: yes
    state: started
- name: Create dirs for dehydrated
  file:
    path: "{{ item.dirname }}"
    state: directory
  with_items: "{{ dehydrated_dirs }}"
- name: Create Domain www dir
  file:
    path: "/www/{{ item.servername }}/html"
    state: directory
  with_items: "{{ nginx_vhosts }}"
- name: Copy nginx file
  template:
    src: nginx.j2
    dest: /etc/nginx.conf
  notify:
    - reloaded nginx
- name: Create vhost files
  template:
     src: vhost.j2
     dest: "/etc/nginx/sites-available/{{ item.servername }}.conf"
  with_items: "{{ nginx_vhosts }}"
  notify:
    - reloaded nginx
- name: Create index.htm files
  template:
     src: index.j2
     dest: "/www/{{ item.servername }}/html/index.htm"
  with_items: "{{ nginx_vhosts }}"
- name: Create sylinks
  file:
    src: "/etc/nginx/sites-available/{{ item.servername }}.conf"
    dest: "/etc/nginx/sites-enabled/{{ item.servername }}.conf"
    state: link
    force: true
  with_items: "{{ nginx_vhosts }}"
  notify:
    - reloaded nginx
 
# cat roles\certs\tasks\main.yml
---
# tasks file for letsencrypt
- name: Lets Encrypt setup
  ansible.builtin.apt:
    name: dehydrated
    state: latest
- name: Copy config from local to vps
  copy:
    src: ./config
    dest: /etc/dehydrated/config
- name: Create domain list file when it not exist
  copy:
    force: false
    content: "{{ item.servername }}"
    dest: "{{ domain_list_file_path }}"
  with_items: "{{ nginx_vhosts }}"
- name: Register account dehydrated
  shell: |
    /usr/bin/dehydrated --register --accept-terms
- name: Get certs
  shell: |
    /usr/bin/dehydrated -c
- name: Enable cert path in config
  shell: |
    sed -i '/^#/s/^#//g' "/etc/nginx/sites-enabled/{{ item.servername }}.conf"
  with_items: "{{ nginx_vhosts }}"
  notify:
    - reloaded nginx
- name: Add job renew certs in cron.
  ansible.builtin.cron:
    name: "Add request certs job"
    user: root
    weekday: "2"
    minute: "0"
    hour: "1"
    job: "/usr/bin/dehydrated -c"
 
Для роли certs сделайте обычные ссылки на vars и handlers из роли nginx
 
Запуск:
# ansible-playbook playbook.yml -i hosts.yml --tags install_nginx
# ansible-playbook playbook.yml -i hosts.yml --tags get_certs
 

Комментарии пользователей

Эту новость ещё не комментировалиНаписать комментарий
Анонимам нельзя оставоять комментарии, зарегистрируйтесь!

Контакты Группа ВК Сборник материалов по Cisco, Asterisk, Windows Server, Python и Django, SQL и T-SQL, FreeBSD и LinuxКод обмена баннерами Видео к IT статьям на YoutubeВидео на другие темы Смотреть
Мои друзья: Советы, помощь, инструменты для сис.админа, статическая и динамическая маршрутизация, FreeBSD

© Snakeproject.ru создан в 2013 году.
При копировании материала с сайта - оставьте ссылку.
Весь материал на сайте носит ознакомительный характер,
за его использование другими людьми, автор ответственности не несет.

Рейтинг@Mail.ru
Рейтинг@Mail.ru Яндекс.Метрика





Поддержать автора и проект