Рубрики
Без рубрики

По требованию, Serverless Valheim Server Server с AWS CDK, дискоментом взаимодействий и GitLab CI

Вот ссылка на репо GitLab, я буду ссылаться в этой статье: https: //gitlab.com/briancaffey … Помечено с CDK, Discord, Valheim, Python.

Вот ссылка на репо GitLab, я буду ссылаться на эту статью: https://gitlab.com/briancaffey/valheim-cdk-discord-interactions

Это углубленная техническая статья о запуске по требованию, выделенным серверу для Valheim с использованием Web-сервисов Amazon, управляемая командами Slash Slash, новая часть их взаимодействия API, которая в настоящее время находится в бета-версии. Valheim – это игра на открытом воздухе онлайн-многопользовательской выживаемости, основанная на мифологии Norse, которая взорвалась недавно.

Моя главная цель с этим проектом было находить недорогой способ запуска сервера, учитывая, как мои друзья и я играю в игру, что обычно несколько раз в неделю по вечерам. Некоторые комбинации из 4 из нас начнут играть, и мы входим и выходим между ходьбой собаки, приготовление пищи и т. Д. При воспроизведении мы все прыгаем на выделенный голосовой канал в раздоре нашей группы.

Перед настройкой выделенного сервера всемирное состояние нашего игры было сохранено на файлах, которые жили на одном из наших компьютеров, и этот компьютер, необходимый для того, чтобы запустить игровой сервер, чтобы любой мог подключиться. Отправка файлов можно было бы возможно, но быстро станет утомительным. Есть много услуг, которые предлагают выделенные серверы для Valheim, а также многие технические руководства и каналы на официальном сервере Valheim DiscoD для поддержки использования выделенных серверов. Я хотел посмотреть, смогу ли я настроить сервер сам на AWS, используя CDK, или набор облачных разработок. CDK – это инфраструктура в качестве инструмента Code (IAC), который позволяет определять, развертывать и обновлять инфраструктуру AWS с популярными языками программирования, такими как Python, Teamscript, Java и т. Д.

CDK-Valheim Construct на Github

Лучшая часть CDK заключается в том, что она позволяет создавать высокоуровневые, многоразовые конструкции, которые могут быть опубликованы на программные реестры, такие как NPM и PYPI. Разработчики могут импортировать и использовать эти конструкции в собственном коде CDK. Быстрый поиск Google для «CDK Valheim» оказался несколько результатов. CDK-Valheim Похоже, лучший вариант для того, что я искал. Этот проект использует ECS, инструмент для оркестрации контейнера от AWS, который у меня есть опыт использования с веб-приложениями и EFS для постоянного хранения файлов. Хотя он написан в Teadercript, я все еще могу использовать конструкцию в моем предпочтительном языке программирования (Python) без каких-либо дополнительных усилий или конфигурации. Это благодаря JSII. От https://github.com/aws/jsii :

JSII Позволяет коду на любом языке, чтобы естественно взаимодействовать с классами JavaScript. Это технология, которая позволяет комплектую облачной разработки AWS для доставки библиотек полиглот из одной кодовой базы!

Вот обзор CDK-Valheim Конструкция:

  • Запланированное масштабирование службы ECS с использованием AWS Fargate (Serverless Compute Engine для контейнеров)
  • Файловая система эластичной файловой системы (EFS) установлена в контейнер на нашей службе Fargate Cass
  • Дополнительные автоматизированные резервные копии файловой системы EFS с использованием AWS Backup

Раздорные взаимодействия и команды Slash

Запланированные масштабирование ECS приятно, но мы не всегда знаем, когда мы сможем играть вместе, так что это не лучший способ минимизировать расходы на инфраструктуру. Мой план состоял в том, чтобы установить службу ECS на первоначальную задачу подсчета ноль, а затем позволит любому из нас установить количество задач на нулю или один через команду SLASH DiscoD. Команда SLASH позволяет вам взаимодействовать с раздорным ботом, набрав / а затем в табуле до опции мы хотим, например /Valheim Server Start или /Valheim Server Status Отказ

Призывая команду SLASH из DiscoD отправляет Пост Запрос от DiscoD в URL-адрес веб -ook, который мы должны предоставить. Чтобы обрабатывать веб -ook, один простой и недорогой подход состоит в том, чтобы использовать Gateway API и функцию лямбда, которая обслуживает приложение для колба. Приложение Flask может затем использовать BOTO3 (который включен в среду выполнения лямбда), чтобы позвонить update_service или Опишите_Сервизы Чтобы масштабировать задачу ECS желанныйКунтируется На основании вариантов команд SLASH и дополнительных опций.

Функция, которая обрабатывает веб -ook Пост Запрос, когда подкомая команда Статус Запросы AWS для количества задач ECS в нашем сервисе, которые являются Желаемый , Бег и в ожидании А затем отправляет обратно сообщение, которое будет отображаться пользователю, который отправил команду. Когда подкомая команда Начало или Стоп , желанныйКунтируется либо устанавливается на 1 или 0 Отказ

Вот обзор настроек сервера и как командам Slash DiscoD можно использовать для управления сервером:

Я накрою каждый из шагов, помеченных на этой диаграмме в конце статьи. Остальная часть статьи предоставит подробные инструкции для того, как все настроить. Я не буду переходить на настройку учетной записи AWS или Setup Server Server.

Как настроить приложение разработчика разрабатывателя и взаимодействия

Во-первых, вы должны быть администратором сервера раздора. Как только вы создадите сервер, перейдите в Настройки сервера> Виджет и обратите внимание на идентификатор сервера. Это также известно как идентификатор гильдии.

Тогда иди к https://discord.com/developers/applications и создать приложение. Под Общая информация Сделайте записку открытого ключа (ID приложения). Поместите эти значения в файл, который будет .Gitignored называется .env.env. :

export GUILD_ID=123456789
export APPLICATION_ID=abc123

Мы будем использовать этот файл позже при регистрации взаимодействия.

Далее иди к OAUTH2 вкладка и выберите бот и Приложения.commands Разрешения. Это сгенерирует ссылку авторизации OAUTT2. Скопируйте ссылку и откройте его в браузере. Мы увидим ошибку:

OAuth2 application does not have a bot

Настройте бот для нашего раздора

Далее, добрался до Бот вкладка и нажмите Добавить бот кнопка.

Добавление пользователя BOT дает вашему приложению видимой жизни в раздоре. Однако это действие безвозвратно! Выбирать мудро.

Выключить Общественный бот Опция и сохранить изменения.

Получите токен бота, нажав на Нажмите, чтобы показать токен и добавьте это в .env.env. :

export BOT_TOKEN=abc.xyz.123

Теперь вернитесь к OAUTH2 вкладка и выберите бот и Приложения.commands. Разрешения снова, скопируйте ссылку и откройте ее. Выберите сервер, который вы хотите добавить это приложение. Вы должны увидеть капчу, а затем сообщение, которое говорит Уполномоченный Отказ Вы также должны увидеть сообщение с вашего дискодер-сервера, что БОТ присоединился к серверу.

Создать взаимодействие

Теперь мы создадим взаимодействие. В настоящее время единственный способ настроить взаимодействие через http Пост запрос. Этот сценарий Python устанавливает наше взаимодействие:

"""
https://discord.com/developers/docs/interactions/slash-commands#registering-a-command
"""

import os

import requests

APPLICATION_ID = os.environ.get("APPLICATION_ID")
GUILD_ID = os.environ.get("GUILD_ID")
BOT_TOKEN = os.environ.get("BOT_TOKEN")

url = f"https://discord.com/api/v8/applications/{APPLICATION_ID}/guilds/{GUILD_ID}/commands"

json = {
    "name": "vh",
    "description": "Start, stop or get the status of the Valheim server",
    "options": [
        {
            "name": "valheim_server_controls",
            "description": "What do you want to do?",
            "type": 3,
            "required": True,
            "choices": [
                {
                    "name": "status",
                    "value": "status"
                },
                {
                    "name": "start",
                    "value": "start"
                },
                {
                    "name": "stop",
                    "value": "stop"
                }
            ]
        },
    ]
}

headers = {
    "Authorization": f"Bot {BOT_TOKEN}"
}

if __name__ == "__main__":
    r = requests.post(url, headers=headers, json=json)
    print(r.content)

Перед запуском этой команды источник .env файл:

source .env

Затем запустите скрипт:

python3 register_bot.py

Вы должны увидеть этот ответ:

b'{"id": "XXXXXXXXXXXXXX", "application_id": "XXXXXXXXXXXXXX", "name": "vh", "description": "Start, stop or get the status of the Valheim server", "version": "XXXXXXXXXXXXXX", "default_permission": true, "guild_id": "XXXXXXXXXXXXXX", "options": [{"type": 3, "name": "valheim_server_controls", "description": "What do you want to do?", "required": true, "choices": [{"name": "status", "value": "status"}, {"name": "start", "value": "start"}, {"name": "stop", "value": "stop"}]}]}'

Теперь, когда вы вводите / В любом канале на сервере DiscOdd вы аутентифицировали бот, вы должны увидеть VH Команда в верхней части списка вариантов автозаполнения.

Если мы запустим любую из этих команд, мы должны увидеть ответ:

This interaction failed

Это потому, что мы не настроили Взаимодействия Конечная точка URL под Общая информация Секция страницы администратора приложения нашего раздора ( https://discord.com/developers/applations/ ).

Настройка URL Enterpoint взаимодействий для нашей команды SLASH

Для того, чтобы наша команда Slash делать что-либо, нам нужно настроить URL, который раздор будет Пост Данные события взаимодействия, включая информацию, такую как кто отправил взаимодействие, какой канал его отправлен, какие опции были использованы и т. Д. Вы можете увидеть пример полезной нагрузки событий здесь, в документации разработчиков группы :

{
    "type": 2,
    "token": "A_UNIQUE_TOKEN",
    "member": {
        "user": {
            "id": 53908232506183680,
            "username": "Mason",
            "avatar": "a_d5efa99b3eeaa7dd43acca82f5692432",
            "discriminator": "1337",
            "public_flags": 131141
        },
        "roles": ["539082325061836999"],
        "premium_since": null,
        "permissions": "2147483647",
        "pending": false,
        "nick": null,
        "mute": false,
        "joined_at": "2017-03-13T19:19:14.040000+00:00",
        "is_pending": false,
        "deaf": false
    },
    "id": "786008729715212338",
    "guild_id": "290926798626357999",
    "data": {
        "options": [{
            "name": "cardname",
            "value": "The Gitrog Monster"
        }],
        "name": "cardsearch",
        "id": "771825006014889984"
    },
    "channel_id": "645027906669510667"
}

Это Пост Запрос также включает в себя некоторые специальные заголовки, используемые для безопасности, которые нам нужно будет выполнить проверку с нашей функцией обработки. Эта часть может быть обработана с декоратором, предоставляемым Разрешенные взаимодействия Пакет на Pypi, но нам нужно будет добавить дополнительную конфигурацию на нашу конечную точку шлюза API, так как эти заголовки не будут переданы через лямбда по умолчанию.

Создание инфраструктуры AWS с помощью CDK

Давайте запустим проект CDK в чистом репозитории, который будет определять нашу инфраструктуру, функции лямбда и конвейера CI/CD с GitLab CI. Убедитесь, что у вас есть AWS-CDK CLI установлен глобально:

npm i -g aws-cdk

Затем запустите проект CDK в подкаталоге под названием CDK с участием:

mkdir cdk && cd cdk && cdk init app --language=python

Добавить зависимости проекта CDK

Следующим шагом является добавление всех зависимостей на наш проект CDK, который мы будем использовать в этом проекте. В setup.py Добавьте следующее:

    install_requires=[
        "aws-cdk.core==1.92.0",
        "aws-cdk.aws_applicationautoscaling==1.92.0",
        "aws-cdk.aws_datasync==1.92.0",
        "aws-cdk.aws_lambda==1.92.0",
        "aws-cdk.aws_s3==1.92.0",
        "aws-cdk.aws_apigateway==1.92.0",
        "cdk-valheim==0.0.16",
    ],

Далее мы можем добавить конструкцию CDK для Valheimworld. в cdk_stack.py Файл, который был сгенерирован в нашем проекте, а также импорт для пакетов, которые мы включили в setup.py :

from aws_cdk import core as cdk

from aws_cdk import (
    core,
    aws_datasync as datasync,
    aws_iam as iam,
    aws_lambda as _lambda,
    aws_apigateway as apigw,
    aws_applicationautoscaling as appScaling,
    aws_s3 as s3,
)
from cdk_valheim import ValheimWorld, ValheimWorldScalingSchedule


class CdkStack(cdk.Stack):

    def __init__(self, scope: cdk.Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)
        # The code that defines your stack goes here
        self.valheim_world = ValheimWorld(
            self,
            'ValheimWorld',
            cpu=2048,
            memory_limit_mib=4096,
            schedules=[ValheimWorldScalingSchedule(
                start=appScaling.CronOptions(hour='12', week_day='1-5'),
                stop=appScaling.CronOptions(hour='1', week_day='1-5'),
            )],
            environment={
                "SERVER_NAME": os.environ.get("SERVER_NAME", "CDK Valheim"),
                "WORLD_NAME": os.environ.get("WORLD_NAME", "Amazon"),
                "SERVER_PASS": os.environ.get("SERVER_PASS", "fargate"),
                "BACKUPS": 'false',
            })

Мы почти готовы развертывать базовую версию нашего сервера Valheim, используя CDK-Valheim построить. Если бы мы работали в следующей команде:

cdk deploy --app cdk/app.py --require-approval never

Из корня нашего проекта он должен работать. Это предполагает, что у нас есть учетные данные по умолчанию, настроенные в ~/.aws/учетные данные И что мы также загрузили нашу учетную запись AWS с ресурсами, которые нужно для работы CDK:

cdk bootstrap --app cdk/app.py aws://$AWS_ACCOUNT_ID/$AWS_DEFAULT_REGION

Настройка Gitlab CI Работа для автоматического развертывания

Вместо развертывания из командной строки было бы лучше запустить развертывание с конвейера CI/CD. Добавить .gitlab-ci.yml Файл в корню вашего проекта и заполните его следующим YAML:

stages:
  - deploy

image: python:3.8

cdk_deploy:
  stage: deploy
  rules:
    - if: "$CI_COMMIT_TAG"
      when: always
  before_script:
    - apt-get -qq update && apt-get -y install nodejs npm
    - npm i -g aws-cdk
    - pip3 install -e cdk
  script:
    - cdk bootstrap --app cdk/app.py aws://$AWS_ACCOUNT_ID/$AWS_DEFAULT_REGION
    - cdk deploy --app cdk/app.py --require-approval never

Прежде чем назначить репозиторий Git в корневом каталоге нашего проекта, удалите озвучивать Репо, что CDK создан, когда мы инициализировали проект с помощью RF -RF CDK/.GIT Отказ Теперь инициализировали проект в корневом каталоге с Git init Отказ

Далее создайте репозиторий GitLab и добавьте пульт дистанционного управления с помощью:

git remote add origin git@gitlab.com:gitlab-username/project-name.git

В проекте GitLab Настройки> CI/CD> Переменные Раздел, добавьте следующие переменные среды в качестве защищенных переменных:

  • Aws_access_key_id.
  • Aws_secret_access_key.
  • Aws_default_region.
  • Aws_account_id.
  • Application_public_key.
  • Server_pass.
  • ИМЯ СЕРВЕРА
  • World_Name.

Сейчас под Настройки> Репозиторий> Защищенные теги Добавьте подстановочный знак ( * ), чтобы все теги были защищены, и только сопровождающие могут нажимать теги. Это позволяет нам использовать защищенные переменные среды только тогда, когда доверенный накопитель подталкивает тег в репозиторий.

Отредактируйте имя стека и добавить регион и информацию о учетной записи

Мы почти готовы создать тег и подтолкнуть к GitLab, но прежде чем мы сделаем это, давайте изменим имя стопки облака, что CDK создаст в cdk/app.py :

#!/usr/bin/env python3

import os

from aws_cdk import core as cdk

# For consistency with TypeScript code, `cdk` is the preferred import name for
# the CDK's core module.  The following line also imports it as `core` for use
# with examples from the CDK Developer's Guide, which are in the process of
# being updated to use `cdk`.  You may delete this import if you don't need it.
from aws_cdk import core

from cdk.cdk_stack import CdkStack

aws_region = os.environ.get("AWS_DEFAULT_REGION", "us-east-1")
aws_account = os.environ.get("AWS_ACCOUNT_ID", "")


app = cdk.App()
CdkStack(
    app,
    "valheim-server-stack",
    env={"region": aws_region, "account": aws_account}
)

app.synth()

Сейчас коммитируйте изменения, создайте тег и нажмите его в GitLab:

git add .
git commit -m "initial commit"
git tag v0.0.1
git push origin v0.0.1

Проверьте журналы трубопровода Gitlab CI, которые это создает в настройках CI/CD проекта GitLab.

Если все работает успешно, вы сможете увидеть свой Valheim Server, перечисленный в списке серверов сообществ, как только он наступит в Интернет, и вы сможете подключиться к нему с паролем, который вы установлены в переменных проекта GitLab.

Добавьте код обработчика функции лямбда

У нас будет простое приложение для колбы отвечать на раздор СООБЩЕНИЕ запросы, которые отправляют события взаимодействия. Давайте добавим лямбда-andler.py в лямбда/функции/взаимодействия/lambda-andhandler.py и требования .txt в лямбда/функции/взаимодействия/требования .txt Отказ Наша структура проекта должна выглядеть так:

$ tree -L 4
.
├── cdk
│   ├── app.py
│   ├── cdk
│   │   ├── cdk_stack.py
│   │   └── __init__.py
│   ├── cdk.json
│   ├── README.md
│   ├── requirements.txt
│   ├── setup.py
│   └── source.bat
├── lambda
│   └── functions
│       └── interactions
│           ├── lambda-handler.py    <-- here
│           └── requirements.txt     <-- and here
├── README.md
└── register_bot.py

требования .txt Определяет зависимости PIP для нашей ламбда. Он должен включать следующее:

aws-wsgi==0.2.7
discord-interactions==0.2.0
Flask==1.1.2
  • AWS-WSGI Превратит запросы шлюза API в запросы на приложение WSGI, которую справится с этой колбой
  • Разрешенные взаимодействия поможет нам с некоторыми требованиями, связанными с безопасностью
  • Колбу Будет наш веб-прикладной

Вот код для лямбда-andler.py :

import os
import logging

import awsgi
import boto3
from discord_interactions import verify_key_decorator
from flask import (
    Flask,
    jsonify,
    request
)


client = boto3.client('ecs')

# Your public key can be found on your application in the Developer Portal
PUBLIC_KEY = os.environ.get('APPLICATION_PUBLIC_KEY')

logger = logging.getLogger()
logger.setLevel(logging.INFO)

app = Flask(__name__)


@app.route('/discord', methods=['POST'])
@verify_key_decorator(PUBLIC_KEY)
def index():
    if request.json["type"] == 1:
        return jsonify({"type": 1})
    else:
        logger.info(request.json)
        try:
            interaction_option = request.json["data"]["options"][0]["value"]
        except KeyError:
            logger.info("Could not parse the interaction option")
            interaction_option = "status"

        logger.info("Interaction:")
        logger.info(interaction_option)

        content = ""

        if interaction_option == "status":
            try:

                resp = client.describe_services(
                    cluster=os.environ.get("ECS_CLUSTER_ARN", ""),
                    services=[
                        os.environ.get("ECS_SERVICE_NAME", ""),
                    ]
                )
                desired_count = resp["services"][0]["desiredCount"]
                running_count = resp["services"][0]["runningCount"]
                pending_count = resp["services"][0]["pendingCount"]

                content = f"Desired: {desired_count} | Running: {running_count} | Pending: {pending_count}"

            except Error as e:
                content = "Could not get server status"
                logger.info("Could not get the server status")
                logger.info(e)

        elif interaction_option == "start":
            content = "Starting the server"

            resp = client.update_service(
                cluster=os.environ.get("ECS_CLUSTER_ARN", ""),
                service=os.environ.get("ECS_SERVICE_NAME", ""),
                desiredCount=1
            )

        elif interaction_option == "stop":
            content = "Stopping the server"

            resp = client.update_service(
                cluster=os.environ.get("ECS_CLUSTER_ARN", ""),
                service=os.environ.get("ECS_SERVICE_NAME", ""),
                desiredCount=0
            )

        else:
            content = "Unknown command"

        logger.info(resp)

        return jsonify({
            "type": 4,
            "data": {
                "tts": False,
                "content": content,
                "embeds": [],
                "allowed_mentions": { "parse": [] }
            }
        })

def handler(event, context):
    return awsgi.response(
        app,
        event,
        context,
        base64_content_types={"image/png"}
    )

Обратите внимание, как мы проходим колбу приложение к awsgi.response Отказ AWS-WSGI (или awsgi Как оно импортируется) – это переход для шлюза API и WSGI.

Добавьте код CDK для Gateway API и лямбда, который будет служить нашему URL-каналу

Теперь мы можем добавить следующий код для cdk_stack.py Чтобы настроить шлюз API и функцию лямбда. Добавьте следующее в cdk_stack.py После нашего определения self.valheim_world :

        self.env_vars = {
            "APPLICATION_PUBLIC_KEY": os.environ.get("APPLICATION_PUBLIC_KEY"),
            "ECS_SERVICE_NAME": self.valheim_world.service.service_name,
            "ECS_CLUSTER_ARN": self.valheim_world.service.cluster.cluster_arn
        }

        self.flask_lambda_layer = _lambda.LayerVersion(
            self,
            "FlaskAppLambdaLayer",
            code=_lambda.AssetCode("./layers/flask"),
            compatible_runtimes=[_lambda.Runtime.PYTHON_3_8,],
        )

        self.flask_app_lambda = _lambda.Function(
            self,
            "FlaskAppLambda",
            runtime=_lambda.Runtime.PYTHON_3_8,
            code=_lambda.AssetCode('./lambda/functions/interactions'),
            function_name="flask-app-handler",
            handler="lambda-handler.handler",
            layers=[self.flask_lambda_layer],
            timeout=core.Duration.seconds(60),
            environment={**self.env_vars},
        )

        self.flask_app_lambda.role.add_managed_policy(
            iam.ManagedPolicy.from_managed_policy_arn(
                self,
                'ECS_FullAccessPolicy',
                managed_policy_arn='arn:aws:iam::aws:policy/AmazonECS_FullAccess'
            )
        )

        # https://slmkitani.medium.com/passing-custom-headers-through-amazon-api-gateway-to-an-aws-lambda-function-f3a1cfdc0e29
        self.request_templates = {
            "application/json": '''{
                "method": "$context.httpMethod",
                "body" : $input.json("$"),
                "headers": {
                    #foreach($param in $input.params().header.keySet())
                    "$param": "$util.escapeJavaScript($input.params().header.get($param))"
                    #if($foreach.hasNext),#end
                    #end
                }
            }
            '''
        }

        self.apigateway = apigw.RestApi(
            self,
            'FlaskAppEndpoint',
        )

        self.apigateway.root.add_method("ANY")

        self.discord_interaction_webhook = self.apigateway.root.add_resource("discord")

        self.discord_interaction_webhook_integration = apigw.LambdaIntegration(
            self.flask_app_lambda,
            request_templates=self.request_templates
        )

        self.discord_interaction_webhook.add_method(
            'POST',
            self.discord_interaction_webhook_integration
        )

Сначала добавляем некоторые переменные среды, которые будут доступны для среды выполнения функции Lambda. Кластер ECS и название обслуживания, а также наше приложение «Разрушение» Public_key нужны в функции лямбда для всего, чтобы работать.

Мы должны дать разрешения функции лямбда, чтобы внести изменения в ECS, поскольку она будет взаимодействовать с ECS через BOTO3.

Self.request_templates необходим для того, чтобы пройти специальные заголовки безопасности от раздора Пост запрос, необходимый для безопасности. Я не мог найти много ресурсов о том, как сделать эту работу, но я узнал, что это использует язык шаблона скорости Apache.

Добавьте работу Gitlab CI для установки зависимостей на слой лямбда

Есть еще один шаг, прежде чем мы сможем толкать наш код. Нам нужно добавить еще одну задаю Gitlab CI, которая установит лямбда-зависимости, чтобы их можно было отправить на слой лямбда, который мы определили в нашей функции лямбда. Слой лямбда – это то, где вы устанавливаете зависимости для этого типа LAMBDA SETUP. Добавим следующий этап:

stages:
  - build
  - deploy

image: python:3.8

pip_install:
  stage: build
  rules:
    - if: "$CI_COMMIT_TAG"
      when: always
  artifacts:
    paths:
      - layers/flask/python
  script:
    - pip install -r lambda/functions/interactions/requirements.txt -t layers/flask/python

Теперь мы устанавливаем зависимости в целевое место (с флагом -t ), что наш LAMBDA-слой сможет использовать в cdk_deploy Gitlab CI Job. Это потому, что мы указали путь к Слои/колба/Python в Пути массив Артефакты в Pip_install работа. Есть и другие способы добавления зависимостей PIP к слоям лямбда. Мы не обязательно не нуждаемся в этом, чтобы сделать в отдельной работе CI.

Теперь тег и нажмите код в GitLab и проверьте, чтобы увидеть, что трубопровод успешно работает.

Добавьте URL-адрес шлюза API, чтобы разделить настроек приложения

Если все работает гладко, мы должны увидеть URL в самых последних строчках трубопровода. Это URL для нашей конечной точки шлюза API:

https://abc123xyz.execute-api.us-east-1.amazonaws.com/prod/

Нам нужно добавить Раздор до конца этого URL, а затем добавьте это к нашему Взаимодействия Конечная точка URL в Общая информация Раздел страницы администратора приложения нашего раздора:

https://abc123xyz.execute-api.us-east-1.amazonaws.com/prod/discord

Когда мы добавляем этот URL в настройках приложения, раздор убедитесь, что наша конечная точка должным образом проверяет запрос на основе его заголовков. Проверьте Эта функция Чтобы увидеть, как это работает:

def verify_key_decorator(client_public_key):
    from flask import request, jsonify

    # https://stackoverflow.com/questions/51691730/flask-middleware-for-specific-route
    def _decorator(f):
        @wraps(f)
        def __decorator(*args, **kwargs):
            # Verify request
            signature = request.headers.get('X-Signature-Ed25519')
            timestamp = request.headers.get('X-Signature-Timestamp')
            if signature is None or timestamp is None or not verify_key(request.data, signature, timestamp, client_public_key):
                return 'Bad request signature', 401

            # Automatically respond to pings
            if request.json and request.json.get('type') == InteractionType.PING:
                return jsonify({
                    'type': InteractionResponseType.PONG
                })

            # Pass through
            return f(*args, **kwargs)
        return __decorator
    return _decorator

Если он не проникнет проверки, мы не сможем добавить URL-адрес, и это не будет работать. Возможно, вы захотите добавить дополнительную регистрацию в функцию лямбда, если вы не сможете успешно добавить URL.

Это все покрыто Документация для взаимодействия разногласий Отказ

Теперь вы должны иметь возможность запустить команды Slash Slash. Вы можете получить статус кластера вашего ECS и масштабировать его на 1 или 0 для На и Выкл. Отказ

Обзор

Вот обзор того, что мы покрыли:

  1. Это мой компьютер. Для разработки этого проекта (и большинства других проектов) я использовал Windows с WSL2.

  2. Gitlab ci – Это используется для запуска наших автоматизированных трубопроводов всякий раз, когда мы нажимаем тег.

  3. CDK CLI используется для создания, обновления и удаления инфраструктуры в нашей учетной записи AWS.

  4. Valheim – клиент для игрового сервера, который мы создали

  5. Общественный IP-адрес задачи ECS, которая может использоваться для подключения к нашему серверу на порту 2456.

  6. Кластер ECS, который управляет фактическим контейнером Docker для Valheim Server. По умолчанию использован изображение Lloesche/Valheim-Server Отказ

  7. EFS – это файловая система, которая устанавливается на контейнер задачи ECS, где хранятся мировые данные нашей игры.

  8. AWS Backup (необязательно) – Это необязательная особенность CDK-Valheim Конструкция, которая может сделать регулярные резервные копии нашей файловой системы EFS.

  9. События (необязательно) – события AWS могут использоваться для масштабирования количества задач ECS от 0 до 1.

  10. Это CDK-Valheim Построить, которые я использую в этом проекте.

  11. Ведро S3 для синхронизации данных и от EFS и от DataSync (WIP)

  12. DataSync для перемещения игрных данных между EFS и S3.

  13. Команды Slash, которые мы настроили

  14. Раздор

  15. Раздорные взаимодействия отправляют и A Пост запрос

  16. Конечная точка шлюза API конечная точка, которую мы настроили для обработки взаимодействия раздора Пост Запросы.

  17. Функция лямбда работает простое приложение для колбы, которое отвечает на взаимодействие Пост запрос.

  18. BOTO3 – это библиотека Python AWS SDK Python, включенная в среду выполнения Python, которая позволяет нам взаимодействовать с ресурсами в нашей учетной записи AWS. В частности, взаимодействия, которые мы используем из BOTO3, являются update_service а также Опишите_сервис Методы из модуля ECS. Это позволяет нам включить и выключить наш сервер, а также получить статус.

  19. Это представляет Valheim-Server-Stack Мы определили в нашем приложении CDK.

СДЕЛАТЬ

Есть еще некоторые вещи, которые я работаю над доработкой.

  • DataSync для легко перемещения данных между S3 и EFS
  • Сообщите данные выставления счетов с дополнительной командой SLASH Sub-Command
  • Добавьте теги к ресурсам в нашем стеке, чтобы облегчить реализацию команда выставления счетов.
  • Получите отзывы от раздора, CDK и Valheim сообществ о том, что я могу улучшить здесь
  • Внести свой вклад в GotoyDoy/CDK-Valheim

Спасибо за прочтение!

Оригинал: “https://dev.to/briancaffey/on-demand-serverless-valheim-server-setup-with-aws-cdk-discord-interactions-and-gitlab-ci-58pj”