DevOps: infrastructure automation with Terraform, docker, bash, prometheus exporters, Gitlab and WireGuard

Hello everyone.





There are people who work with cloud infrastructure and do not use automation, because it takes a long time, you need to delve into, and they need to cut features. We clicked something there in the UI, connected via ssh, installed everyone using apt, etc. and the configuration files were manually changed. Of course, there was not enough time to write the documentation, or there are many different tricky steps in it and it is no longer possible or very difficult to repeat the configuration of this infrastructure exactly, and the services are spinning in production. And then the person forgot what and how he did exactly or quit altogether.





I want to show with a small example that it can be quite simple and pleasant to automate infrastructure, for example, in AWS, and the resulting result is quite transparent and is itself a documentation, since it's infrastructure as code. If, of course, you have knowledge of Terraform or a desire to study it a little.





By the way, I highly recommend a lot of things for automation, but especially cloud providers like AWS / GCP / Azure, etc. use Terraform, because it is a fairly mature tool, it has a large community and, among other things, it supports the automation of not only some cloud providers, but almost everything that has an API. In addition, the tool is open source and, if you wish, you can implement anything yourself. For clouds like AWS, I do not recommend trying to implement automation with pure python and requests to AWS API using cli or Cloudformation.





Also, Terraform has a convenient ability to organize your code into blocks called modules and passing only parameters to them, it is easy to create what you need with other settings.





, Terraform , .tf Terraform , Terraform , . main.tf - .





, , vpn WireGuard Ubuntu 20.04 + . WireGuard linux, , , .





.





.





, , . .





, iam , ..





elastic ip, , dns , vpn . geo dns route53, ip vpn , .. route53 , .





security groups , vpn udp (Wireguard udp) + ssh + prometheus exporter'.





/ ec2 , , auto scaling group, . , - , . Self healing.





load balancer , auto scaling groups : - , cpu, vpn , .





Terraform, Terragrunt, Keep your Terraform code DRY, backend , Terraform . Terraform , , , S3 . , , Dynamodb, - .





.





terragrunt.hcl (https://github.com/vainkop/terraform-aws-wireguard/blob/master/example/terragrunt.hcl) , , state , terragrunt.hcl find_in_parent_folders()



https://github.com/vainkop/terraform-aws-wireguard/blob/master/example/us-east-1/terragrunt.hcl#L2





key, .. , , path_relative_to_include()



https://github.com/vainkop/terraform-aws-wireguard/blob/master/example/terragrunt.hcl#L11





/ yaml , yamldecode(file(...))



https://github.com/vainkop/terraform-aws-wireguard/blob/master/example/eu-central-1/terragrunt.hcl#L9





( YOUR_...



): https://github.com/vainkop/terraform-aws-wireguard/blob/master/example/us-east-1/values.yaml





, region , , basename(get_terragrunt_dir())



values.yaml



, .





, - ci cd runner example, .. terragrunt.hcl



yaml , , . "" yaml Terraform .





: -, Terraform . , .





, open source , , , source = "github.com/vainkop/terraform-aws-wireguard?ref=v1.2.0"



https://github.com/vainkop/terraform-aws-wireguard/blob/master/example/eu-central-1/terragrunt.hcl#L6





open source , , .





cloud-init , , auto scaling group, : https://github.com/vainkop/terraform-aws-wireguard/blob/master/templates/user-data.txt





2 prometheus exporter', ec2 , WireGuard, Dashboards alerts ..





, vpn , , , , .. vpn . .. , geo ip route53.





.gitlab-ci.yml



Dockerfile



Gitlab runner' docker runner'.





$ cat .gitlab-ci.yml

stages:
  - build
  - plan
  - apply
  - destroy

variables:
  GIT_DEPTH: 1

.aws_configure: &aws_configure
  before_script:
    - aws configure set aws_access_key_id $AWS_ACCESS_KEY_ID
    - aws configure set aws_secret_access_key $AWS_SECRET_ACCESS_KEY
    - aws configure set default.region $AWS_DEFAULT_REGION


build-terraform:
  image: docker:19.03.15
  services:
    - docker:19.03.15-dind
  stage: build
  variables:
    DOCKER_TLS_CERTDIR: ""
    DOCKER_HOST: tcp://docker:2375
    DOCKER_DRIVER: overlay2
    TERRAFORM_VERSION: "0.13.6"
    TERRAGRUNT_VERSION: "v0.28.9"
  before_script:
    - printenv
    - docker info
    - echo $CI_REGISTRY_PASSWORD | docker login $CI_REGISTRY -u $CI_REGISTRY_USER --password-stdin
  script:
    - cd docker
    - docker build --build-arg TERRAFORM_VERSION=$TERRAFORM_VERSION --build-arg TERRAGRUNT_VERSION=$TERRAGRUNT_VERSION -t $CI_REGISTRY_IMAGE:$TERRAFORM_VERSION .
    - docker push $CI_REGISTRY_IMAGE:$TERRAFORM_VERSION
  rules:
    - changes:
        - docker/*


plan-us-east-1:
  image:
    name: registry.gitlab.com/vainkop/terraform:0.13.6
    entrypoint: [""]
  stage: plan
  <<: *aws_configure
  script:
    - cd wireguard/us-east-1
    - terragrunt run-all plan --terragrunt-non-interactive -out $CI_PROJECT_DIR/wireguard/us-east-1/tfplan-$CI_COMMIT_SHA
  artifacts:
    paths:
    - $CI_PROJECT_DIR/wireguard/us-east-1/tfplan-$CI_COMMIT_SHA
    expire_in: 1 month
  rules:
    - changes:
        - wireguard/us-east-1/*
      allow_failure: true

plan-eu-central-1:
  image:
    name: registry.gitlab.com/vainkop/terraform:0.13.6
    entrypoint: [""]
  stage: plan
  <<: *aws_configure
  script:
    - cd wireguard/eu-central-1
    - terragrunt run-all plan --terragrunt-non-interactive -out $CI_PROJECT_DIR/wireguard/eu-central-1/tfplan-$CI_COMMIT_SHA
  artifacts:
    paths:
    - $CI_PROJECT_DIR/wireguard/eu-central-1/tfplan-$CI_COMMIT_SHA
    expire_in: 1 month
  rules:
    - changes:
        - wireguard/eu-central-1/*
      allow_failure: true

apply-us-east-1:
  image:
    name: registry.gitlab.com/vainkop/terraform:0.13.6
    entrypoint: [""]
  stage: apply
  <<: *aws_configure
  script:
    - cd wireguard/us-east-1
    - terragrunt run-all apply --terragrunt-non-interactive -auto-approve $CI_PROJECT_DIR/wireguard/us-east-1/tfplan-$CI_COMMIT_SHA
  rules:
    - changes:
        - wireguard/us-east-1/*
      when: manual
      allow_failure: true

apply-eu-central-1:
  image:
    name: registry.gitlab.com/vainkop/terraform:0.13.6
    entrypoint: [""]
  stage: apply
  <<: *aws_configure
  script:
    - cd wireguard/eu-central-1
    - terragrunt run-all apply --terragrunt-non-interactive -auto-approve $CI_PROJECT_DIR/wireguard/eu-central-1/tfplan-$CI_COMMIT_SHA
  rules:
    - changes:
        - wireguard/eu-central-1/*
      when: manual
      allow_failure: true

destroy-us-east-1:
  image:
    name: registry.gitlab.com/vainkop/terraform:0.13.6
    entrypoint: [""]
  stage: destroy
  <<: *aws_configure
  script:
    - cd wireguard/us-east-1
    - terragrunt run-all destroy --terragrunt-non-interactive -auto-approve
  rules:
    - changes:
        - wireguard/us-east-1/*
      when: manual
      allow_failure: true

destroy-eu-central-1:
  image:
    name: registry.gitlab.com/vainkop/terraform:0.13.6
    entrypoint: [""]
  stage: destroy
  <<: *aws_configure
  script:
    - cd wireguard/eu-central-1
    - terragrunt run-all destroy --terragrunt-non-interactive -auto-approve
  rules:
    - changes:
        - wireguard/eu-central-1/*
      when: manual
      allow_failure: true
      
      



$ cat docker/Dockerfile

FROM ubuntu:20.04

USER root

ARG DEBIAN_FRONTEND=noninteractive

ARG TERRAFORM_VERSION
ENV TERRAFORM_VERSION=$TERRAFORM_VERSION

ARG TERRAGRUNT_VERSION
ENV TERRAGRUNT_VERSION=$TERRAGRUNT_VERSION

RUN set -x && \
    apt-get update && \
    apt-get install -y \
    apt-transport-https \
    ca-certificates \
    software-properties-common \
    unzip \
    net-tools \
    wget \
    curl \
    python3 \
    python3-pip \
    jq \
    gettext-base \
    git && \
    rm -rf /var/lib/apt/lists/*

RUN set -x && \
    apt-key adv --keyserver keyserver.ubuntu.com --recv-keys CC86BB64 && \
    add-apt-repository ppa:rmescandon/yq && \
    apt update && \
    apt install -y yq && \
    rm -rf /var/lib/apt/lists/*

RUN set -x && \
    pip3 install -U --no-cache-dir setuptools shyaml

RUN set -x && \
    ln -sf /usr/bin/python3 /usr/bin/python && ln -sf /usr/bin/pip3 /usr/bin/pip

RUN set -x && \
    curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" && \
    unzip awscliv2.zip && \
    ./aws/install && \
    rm -rf awscliv2.zip && \
    /aws \
    /usr/local/aws-cli/v2/*/dist/awscli/examples

RUN set -x && \
    cd /tmp && \
    curl -O https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_linux_amd64.zip && \
    unzip terraform_${TERRAFORM_VERSION}_linux_amd64.zip -d /usr/local/bin && \
    chmod +x /usr/local/bin/terraform && \
    rm /tmp/terraform_${TERRAFORM_VERSION}_linux_amd64.zip

RUN set -x && \
    wget "https://github.com/gruntwork-io/terragrunt/releases/download/${TERRAGRUNT_VERSION}/terragrunt_linux_amd64" && \
    mv terragrunt_linux_amd64 /usr/local/bin/terragrunt && \
    chmod +x /usr/local/bin/terragrunt

RUN set -x && \
    curl --version && \
    envsubst --version && \
    python --version && \
    pip --version && \
    shyaml --version && \
    jq -V && \
    yq -V && \
    aws --version && \
    terraform --version && \
    terragrunt --version

ENTRYPOINT ["/bin/bash", "-c"]
      
      



, .





/, , , , : @vainkop







I also ask you to take into account that this is my first publication on Habré.








All Articles