코드로서의 인프라

이 콘텐츠는 Azure용 클라우드 네이티브 .NET 애플리케이션 설계 eBook 에서 발췌한 것으로, .NET 문서에서 제공되거나 오프라인 상태에서도 읽을 수 있는 PDF(무료 다운로드 가능)로 제공됩니다.

Cloud Native .NET apps for Azure eBook cover thumbnail.

클라우드 네이티브 시스템은 마이크로 서비스, 컨테이너 및 최신 시스템 디자인을 수용하여 속도와 민첩성을 달성합니다. 일관되고 품질이 좋은 코드를 보장하기 위해 자동화된 빌드 및 릴리스 단계를 제공합니다. 하지만 이는 일부에 불과합니다. 이러한 시스템이 실행되는 클라우드 환경을 어떻게 프로비저닝하나요?

최신 클라우드 네이티브 애플리케이션은 Infrastructure as Code 또는 IaC라는 널리 받아들여지는 사례를 수용합니다. IaC를 사용하면 플랫폼 프로비저닝을 자동화할 수 있습니다. 기본적으로 DevOps 사례에 테스트 및 버전 관리와 같은 소프트웨어 엔지니어링 사례를 적용합니다. 인프라 및 배포는 자동화되고, 일관되며, 반복 가능합니다. 지속적인 업데이트가 기존의 수동 배포 모델을 자동화한 것처럼 IaC(Infrastructure as Code)는 애플리케이션 환경을 관리하는 방식을 발전시키고 있습니다.

ARM(Azure Resource Manager), Terraform 및 Azure CLI(명령줄 인터페이스)와 같은 도구를 사용하면 필요한 클라우드 인프라를 선언적으로 스크립팅할 수 있습니다.

Azure 리소스 관리자 템플릿

ARM은 Azure Resource Manager를 나타냅니다. Azure에 기본 제공되고 API 서비스로 노출되는 API 프로비저닝 엔진입니다. ARM을 사용하면 조정된 단일 작업으로 Azure 리소스 그룹에 포함된 리소스를 배포, 업데이트, 삭제 및 관리할 수 있습니다. 필요한 리소스와 해당 구성을 지정하는 JSON 기반 템플릿을 엔진에 제공합니다. ARM은 종속성과 관련하여 올바른 순서로 배포를 자동으로 오케스트레이션합니다. 엔진은 멱등성을 보장합니다. 원하는 리소스가 이미 동일한 구성으로 존재하는 경우 프로비저닝이 무시됩니다.

Azure Resource Manager 템플릿은 Azure에서 다양한 리소스를 정의하기 위한 JSON 기반 언어입니다. 기본 스키마는 그림 10-14와 같습니다.

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "",
  "apiProfile": "",
  "parameters": {  },
  "variables": {  },
  "functions": [  ],
  "resources": [  ],
  "outputs": {  }
}

그림 10-14 - Resource Manager 템플릿의 스키마

이 템플릿 내에서 다음과 같이 리소스 섹션 내부에 스토리지 컨테이너를 정의할 수 있습니다.

"resources": [
    {
      "type": "Microsoft.Storage/storageAccounts",
      "name": "[variables('storageAccountName')]",
      "location": "[parameters('location')]",
      "apiVersion": "2018-07-01",
      "sku": {
        "name": "[parameters('storageAccountType')]"
      },
      "kind": "StorageV2",
      "properties": {}
    }
  ],

그림 10-15 - Resource Manager 템플릿에 정의된 스토리지 계정의 예

ARM 템플릿은 동적 환경 및 구성 정보로 매개 변수화할 수 있습니다. 이렇게 하면 개발, QA 또는 프로덕션과 같은 다양한 환경을 정의하는 데 재사용할 수 있습니다. 일반적으로 템플릿은 단일 Azure 리소스 그룹 내에 모든 리소스를 만듭니다. 필요한 경우 단일 Resource Manager 템플릿에서 여러 리소스 그룹을 정의할 수 있습니다. 리소스 그룹 자체를 삭제하여 환경의 모든 리소스를 삭제할 수 있습니다. 또한 리소스 그룹 수준에서 비용 분석을 실행하여 각 환경의 비용을 빠르게 파악할 수 있습니다.

GitHub의 Azure 빠른 시작 템플릿 프로젝트에서 사용할 수 있는 ARM 템플릿의 예가 많이 있습니다. 새 템플릿을 만들거나 기존 템플릿을 수정하는 속도를 높이는 데 도움이 될 수 있습니다.

Resource Manager 템플릿은 다양한 방법으로 실행할 수 있습니다. 가장 간단한 방법은 단순히 Azure Portal에 붙여넣는 것입니다. 실험적 배포의 경우 이 방법이 빠를 수 있습니다. Azure DevOps에서 빌드 또는 릴리스 프로세스의 일부로 실행할 수도 있습니다. Azure에 대한 연결을 활용하여 템플릿을 실행하는 작업이 있습니다. Resource Manager 템플릿에 대한 변경 내용은 점분 방식으로 적용됩니다. 즉, 새 리소스를 추가하려면 템플릿에 추가하기만 하면 됩니다. 이 도구는 현재 리소스와 템플릿에 정의된 리소스 간의 차이를 조정합니다. 그러면 리소스가 템플릿에 정의된 것과 일치하도록 만들어지거나 변경됩니다.

Terraform

클라우드 네이티브 애플리케이션은 종종 cloud agnostic으로 구성됩니다. 이렇게 하면 애플리케이션이 특정 클라우드 공급업체와 긴밀하게 연결되지 않고 모든 퍼블릭 클라우드에 배포될 수 있습니다.

Terraform은 Azure, Google Cloud Platform, AWS, AliCloud 등 모든 주요 클라우드 플레이어에 클라우드 네이티브 애플리케이션을 프로비저닝할 수 있는 상용 템플릿 도구입니다. 템플릿 정의 언어로 JSON을 사용하는 대신 약간 더 간결한 HCL(Hashicorp Configuration Language)을 사용합니다.

이전 Resource Manager 템플릿(그림 10-15)과 동일한 작업을 수행하는 Terraform 파일의 예는 그림 10-16에 나와 있습니다.

provider "azurerm" {
  version = "=1.28.0"
}

resource "azurerm_resource_group" "testrg" {
  name     = "production"
  location = "West US"
}

resource "azurerm_storage_account" "testsa" {
  name                     = "${var.storageAccountName}"
  resource_group_name      = "${azurerm_resource_group.testrg.name}"
  location                 = "${var.region}"
  account_tier             = "${var.tier}"
  account_replication_type = "${var.replicationType}"

}

그림 10-16 - Resource Manager 템플릿의 예

Terraform은 문제 템플릿에 대한 직관적인 오류 메시지도 제공합니다. 템플릿 오류를 조기에 catch하기 위해 빌드 단계에서 사용할 수 있는 편리한 유효성 검사 작업도 있습니다.

Resource Manager 템플릿과 마찬가지로 명령줄 도구를 사용하여 Terraform 템플릿을 배포할 수 있습니다. Azure Pipelines에는 Terraform 템플릿의 유효성을 검사하고 적용할 수 있는 커뮤니티 만들기 작업도 있습니다.

경우에 따라 Terraform 및 ARM 템플릿은 새로 만들어진 데이터베이스에 대한 연결 문자열과 같은 의미 있는 값을 출력합니다. 이 정보는 빌드 파이프라인에서 캡처하여 후속 작업에서 사용할 수 있습니다.

Azure CLI 스크립트 및 작업

마지막으로 Azure CLI를 활용하여 클라우드 인프라를 선언적으로 스크립팅할 수 있습니다. Azure CLI 스크립트를 만들고, 찾고, 공유하여 거의 모든 Azure 리소스를 프로비저닝하고 구성할 수 있습니다. CLI는 학습 곡선이 완만하여 사용이 간편합니다. 스크립트는 PowerShell 또는 Bash 내에서 실행됩니다. 특히 ARM 템플릿과 비교할 때 디버그하는 것도 간단합니다.

Azure CLI 스크립트는 인프라를 해체하고 재배포해야 할 때 잘 작동합니다. 기존 환경을 업데이트하는 것은 까다로울 수 있습니다. 많은 CLI 명령은 멱등성이 아닙니다. 즉, 리소스가 이미 존재하더라도 실행할 때마다 리소스를 다시 만듭니다. 만들기 전에 각 리소스의 존재를 확인하는 코드를 항상 추가할 수 있습니다. 그러나 그렇게 하면 스크립트가 부풀려지고 관리하기 어려울 수 있습니다.

이러한 스크립트는 Azure DevOps 파이프라인에 Azure CLI tasks로 포함할 수도 있습니다. 파이프라인을 실행하면 스크립트가 호출됩니다.

그림 10-17은 Azure CLI 버전과 구독 세부 정보를 나열하는 YAML 조각을 보여 줍니다. Azure CLI 명령이 인라인 스크립트에 어떻게 포함되는지 확인하세요.

- task: AzureCLI@2
  displayName: Azure CLI
  inputs:
    azureSubscription: <Name of the Azure Resource Manager service connection>
    scriptType: ps
    scriptLocation: inlineScript
    inlineScript: |
      az --version
      az account show

그림 10-17 - Azure CLI 스크립트

작성자 Sam Guckenheimer는 Infrastructure as Code란 무엇인가 문서에서 "IaC를 구현하는 팀이 안정적인 환경을 신속하고 대규모로 제공”할 수 있는 방법에 대해 설명합니다. 팀은 환경을 수동으로 구성하지 않고 코드를 통해 환경의 원하는 상태를 표시하여 일관성을 적용합니다. IaC를 사용한 인프라 배포는 반복 가능하며 구성 드리프트 또는 누락된 종속성으로 인한 런타임 문제를 방지합니다. DevOps 팀은 통합 사례 및 도구 집합을 함께 사용하여 애플리케이션과 지원 인프라를 신속하고 안정적으로 대규모로 제공할 수 있습니다.