티스토리 뷰
<참조>
https://docs.microsoft.com/ko-kr/azure/terraform/terraform-backend
https://docs.microsoft.com/en-us/azure/terraform/terraform-backend
https://docs.microsoft.com/ko-kr/azure/terraform/terraform-cloud-shell
https://docs.microsoft.com/en-us/azure/terraform/terraform-cloud-shell
Terraform 상태는 Terraform 구성을 사용하여 배포된 리소스를 조정(reconcile)하는 데 사용된다. 상태를 통해 Terraform은 추가, 업데이트 또는 삭제할 Azure 리소스를 파악한다. 기본적으로 Terraform 상태는 terraform apply 명령을 실행할 때 로컬로 저장된다. 이 구성은 다음과 같은 이유로 적합하지 않다.
- 로컬 상태는 팀 또는 협업 환경에서 잘 작동하지 않는다.
- Terraform 상태는 민감한 정보를 포함할 수 있다.
- 상태를 로컬로 저장하면 실수로 삭제할 가능성이 높아진니다.
Terraform은 원격 스토리지에서 상태의 지속을 지원한다. 이렇게 지원되는 백 엔드 중 하나는 Azure Storage이다. 이 문서에서는 이 목적을 위해 Azure Storage를 구성하고 사용하는 방법을 보여 준다.
20200210 추가 정리
여러 사람이 Terraform 작업을 수행햐야 하는 작업환경에서 각자의 컴퓨터에서 리소스 배포를 수행하게 된다. 따라서 현재 상태의 인프라에 대한 정보를 가지는 각각의 tfstate 파일을 가지게 된다. 이는 Single Source Of Truth에 맞지 않다. 모든 작업자가 클라우드 스토리지와 같은 하나의 위치에 배포 할 수 있어야 한다.
Single Source Of Truth, SSOThttps://thenewstack.io/what-kpmg-learned-about-infrastructure-as-code-tools-people-and-process/ IaC는 인프라의 모양을 정의하기 위한 선언적 모델이다. 이 방법에서는 모든 연결을 찾을 수 있다. 다른 프로젝트, 다른 팀과 구성의 비트와 조각을 공유 할 수 있다. 다른 사람들에게 변경사항을 검토하게 할 수 있다.
|
스토리지 계정 구성
Azure Storage를 백 엔드로 사용하기 전에 스토리지 계정을 만들어야 한다. 스토리지 계정은 Azure Portal, PowerShell, Azure CLI 또는 자체 Terraform을 사용하여 만들 수 있다. Azure CLI를 사용하여 스토리지 계정을 구성하려면 다음 샘플을 사용한다.
#!/bin/bash
RESOURCE_GROUP_NAME=tstate STORAGE_ACCOUNT_NAME=tstate$RANDOM CONTAINER_NAME=tstate
# Create resource group az group create --name $RESOURCE_GROUP_NAME --location koreacentral
# Create storage account az storage account create --resource-group $RESOURCE_GROUP_NAME --name $STORAGE_ACCOUNT_NAME --sku Standard_LRS --encryption-services blob
# Get storage account key ACCOUNT_KEY=$(az storage account keys list --resource-group $RESOURCE_GROUP_NAME --account-name $STORAGE_ACCOUNT_NAME --query [0].value -o tsv)
# Create blob container az storage container create --name $CONTAINER_NAME --account-name $STORAGE_ACCOUNT_NAME --account-key $ACCOUNT_KEY
echo "storage_account_name: $STORAGE_ACCOUNT_NAME" echo "container_name: $CONTAINER_NAME" echo "access_key: $ACCOUNT_KEY" |
VS Code를 열고 WSL(bash) 터미널에서 위 샘플을 한줄씩 수행한다.
zerobig@ZEROBIG-NT800:/mnt/c/AzureDevOps-Exercise$ RESOURCE_GROUP_NAME=tstate
zerobig@ZEROBIG-NT800:/mnt/c/AzureDevOps-Exercise$ STORAGE_ACCOUNT_NAME=tstate$RANDOM
zerobig@ZEROBIG-NT800:/mnt/c/AzureDevOps-Exercise$ CONTAINER_NAME=tstate
zerobig@ZEROBIG-NT800:/mnt/c/AzureDevOps-Exercise$ az group create --name $RESOURCE_GROUP_NAME --location koreacentral
{
"id": "/subscriptions/2e5d848e-xxxx-xxxx-xxxx-fd25ae915bcd/resourceGroups/tstate",
"location": "koreacentral",
"managedBy": null,
"name": "tstate",
"properties": {
"provisioningState": "Succeeded"
},
"tags": null,
"type": "Microsoft.Resources/resourceGroups"
}
zerobig@ZEROBIG-NT800:/mnt/c/AzureDevOps-Exercise$ az storage account create --resource-group $RESOURCE_GROUP_NAME --name $STORAGE_ACCOUNT_NAME --sku Standard_LRS --encryption-services blob
The default kind for created storage account will change to 'StorageV2' from 'Storage' in future
{
"accessTier": null,
"azureFilesIdentityBasedAuthentication": null,
"creationTime": "2020-01-05T01:32:06.625304+00:00",
"customDomain": null,
"enableHttpsTrafficOnly": true,
"encryption": {
"keySource": "Microsoft.Storage",
"keyVaultProperties": null,
"services": {
"blob": {
"enabled": true,
"lastEnabledTime": "2020-01-05T01:32:06.672180+00:00"
},
"file": {
"enabled": true,
"lastEnabledTime": "2020-01-05T01:32:06.672180+00:00"
},
"queue": null,
"table": null
}
},
"failoverInProgress": null,
"geoReplicationStats": null,
"id": "/subscriptions/2e5d848e-xxxx-xxxx-xxxx-fd25ae915bcd/resourceGroups/tstate/providers/Microsoft.Storage/storageAccounts/tstate23760",
"identity": null,
"isHnsEnabled": null,
"kind": "Storage",
"largeFileSharesState": null,
"lastGeoFailoverTime": null,
"location": "koreacentral",
"name": "tstate23760",
"networkRuleSet": {
"bypass": "AzureServices",
"defaultAction": "Allow",
"ipRules": [],
"virtualNetworkRules": []
},
"primaryEndpoints": {
"blob": "https://tstate23760.blob.core.windows.net/",
"dfs": null,
"file": "https://tstate23760.file.core.windows.net/",
"queue": "https://tstate23760.queue.core.windows.net/",
"table": "https://tstate23760.table.core.windows.net/",
"web": null
},
"primaryLocation": "koreacentral",
"provisioningState": "Succeeded",
"resourceGroup": "tstate",
"secondaryEndpoints": null,
"secondaryLocation": null,
"sku": {
"capabilities": null,
"kind": null,
"locations": null,
"name": "Standard_LRS",
"resourceType": null,
"restrictions": null,
"tier": "Standard"
},
"statusOfPrimary": "available",
"statusOfSecondary": null,
"tags": {},
"type": "Microsoft.Storage/storageAccounts"
}
zerobig@ZEROBIG-NT800:/mnt/c/AzureDevOps-Exercise$ ACCOUNT_KEY=$(az storage account keys list --resource-group $RESOURCE_GROUP_NAME --account-name $STORAGE_ACCOUNT_NAME --query [0].value -o tsv)
zerobig@ZEROBIG-NT800:/mnt/c/AzureDevOps-Exercise$ az storage container create --name $CONTAINER_NAME --account-name $STORAGE_ACCOUNT_NAME --account-key $ACCOUNT_KEY
{
"created": true
}
zerobig@ZEROBIG-NT800:/mnt/c/AzureDevOps-Exercise$ echo "storage_account_name: $STORAGE_ACCOUNT_NAME"
storage_account_name: tstate23760
zerobig@ZEROBIG-NT800:/mnt/c/AzureDevOps-Exercise$ echo "container_name: $CONTAINER_NAME"
container_name: tstate
zerobig@ZEROBIG-NT800:/mnt/c/AzureDevOps-Exercise$ echo "access_key: $ACCOUNT_KEY"
access_key: inhn3DtNdguuaKgzzX4be5e/8QpxPJutqQWADmu8WfRQtvSahnooZEF99ONenm2zMzybdMkm2rcNZoNGe43+Nw==
스토리지 계정 이름, 컨테이너 이름 및 스토리지 액세스 키를 적어둔다. 이러한 값은 원격 상태를 구성할 때 필요하다.
상태 백 엔드 구성
Terraform 상태 백 엔드는 terraform init 명령을 실행할 때 구성된다. 상태 백 엔드를 구성하려면 다음 데이터가 필요하다.
- storage_account_name: Azure Storage 계정의 이름이다.
- container_name: Blob 컨테이너의 이름이다.
- 키: 만들 상태 저장소 파일의 이름이다.
- access_key: 스토리지 액세스 키다.
이러한 각 값은 Terraform 구성 파일이나 명령줄에서 지정할 수 있다. access_key 값에는 환경 변수를 사용하는 것이 좋다. 환경 변수를 사용하면 키가 디스크에 쓰이는 것을 방지할 수 있다.
Azure Storage 액세스 키의 값을 사용하여 ARM_ACCESS_KEY라는 환경 변수를 만든다.
export ARM_ACCESS_KEY=<storage access key> |
zerobig@ZEROBIG-NT800:/mnt/c/AzureDevOps-Exercise$ export ARM_ACCESS_KEY=inhn3DtNdguuaKgzzX4be5e/8QpxPJutqQWADmu8WfRQtvSahnooZEF99ONenm2zMzybdMkm2rcNZoNGe43+Nw==
Azure Storage 계정 액세스 키를 추가로 보호하려면 Azure Key Vault에 저장한다. 그런 다음, 다음과 비슷한 명령을 사용하여 환경 변수를 설정할 수 있다. Azure Key Vault에 대한 자세한 내용은 Azure Key Vault 설명서를 참조한다.
여기서는 생략하고 넘어가도록 한다.
export ARM_ACCESS_KEY=$(az keyvault secret show --name terraform-backend-key --vault-name myKeyVault --query value -o tsv) |
백 엔드를 사용하도록 Terraform을 구성하려면 다음 단계를 수행해야 한다.
- azurerm 형식의 backend 구성 블록을 포함한다.
- 구성 블록에 storage_account_name 값을 추가한다.
- 구성 블록에 container_name 값을 추가한다.
- 구성 블록에 key 값을 추가한다.
다음 예제에서는 Terraform 백 엔드를 구성하고 Azure 리소스 그룹을 만든다.
terraform { backend "azurerm" { storage_account_name = "tstate23760" container_name = "tstate" key = "terraform.tfstate" } }
resource "azurerm_resource_group" "state-demo-secure" { name = "state-demo" location = "eastus" } |
VS Code에 test.tf 라는 임시파일을 만들고 위 코드를 붙여넣고 저장한다. 이때 storage_account_name은 각자 생성된 리소스 이름을 참조하여 대체한다.
다음 단계를 수행하여 구성을 초기화한다.
1. terraform init 명령을 실행한다.
zerobig@ZEROBIG-NT800:/mnt/c/AzureDevOps-Exercise/20200105$ terraform init
Initializing the backend...
Successfully configured the backend "azurerm"! Terraform will automatically
use this backend unless the backend configuration changes.
Initializing provider plugins...
- Checking for available provider plugins...
- Downloading plugin for provider "azurerm" (hashicorp/azurerm) 1.39.0...
The following providers do not have any version constraints in configuration,
so the latest version was installed.
To prevent automatic upgrades to new major versions that may contain breaking
changes, it is recommended to add version = "..." constraints to the
corresponding provider blocks in configuration, with the constraint strings
suggested below.
* provider.azurerm: version = "~> 1.39"
Terraform has been successfully initialized!
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
zerobig@ZEROBIG-NT800:/mnt/c/AzureDevOps-Exercise/20200105$
2. terraform plan 명령을 먼저 실행하여 적용 전에 문제가 없는지 검토한다.
zerobig@ZEROBIG-NT800:/mnt/c/AzureDevOps-Exercise/20200105$ terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.
------------------------------------------------------------------------
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# azurerm_resource_group.state-demo-secure will be created
+ resource "azurerm_resource_group" "state-demo-secure" {
+ id = (known after apply)
+ location = "koreacentral"
+ name = "state-demo"
+ tags = (known after apply)
}
Plan: 1 to add, 0 to change, 0 to destroy.
------------------------------------------------------------------------
Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.
zerobig@ZEROBIG-NT800:/mnt/c/AzureDevOps-Exercise/20200105$
3. terraform apply 명령을 실행한다.
이제 Azure Storage Blob에서 상태 파일을 찾을 수 있다.
zerobig@ZEROBIG-NT800:/mnt/c/AzureDevOps-Exercise/20200105$ terraform apply
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# azurerm_resource_group.state-demo-secure will be created
+ resource "azurerm_resource_group" "state-demo-secure" {
+ id = (known after apply)
+ location = "koreacentral"
+ name = "state-demo"
+ tags = (known after apply)
}
Plan: 1 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
azurerm_resource_group.state-demo-secure: Creating...
azurerm_resource_group.state-demo-secure: Creation complete after 0s [id=/subscriptions/2e5d848e-xxxx-xxxx-xxxx-fd25ae915bcd/resourceGroups/state-demo]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
zerobig@ZEROBIG-NT800:/mnt/c/AzureDevOps-Exercise/20200105$
상태 잠금
Azure Storage Blob은 상태를 기록하는 모든 작업 이전에 자동으로 잠긴다. 이 패턴은 손상을 일으킬 수 있는 동시 상태 작업을 방지한다.
자세한 내용은 Terraform 설명서의 상태 잠금을 참조한다.
Azure Portal 또는 기타 Azure 관리 도구를 통해 Blob을 검토할 때는 잠겨져 있다.
20200210 추가 정리
terraform apply를 수행하면 터미널에 "Acquiring state lock, This may take a few moments..." 라는 메시지를 출력하며 실제로 lease를 획득(acquired) 한다. 이때 Azure 포털에서 상태를 확인해 보면, Acquire lease 상태임을 확인할 수 있다. ![]() 상태파일을 선택하여 클릭하면 Metadata에 key/value를 확인할 수 있다. ![]() 이 lock 상태는 명령수행이 완료될때까지 지속된다.
|
휴지 상태의 암호화
Azure Blob에 저장된 데이터는 영구 저장되기 전에 암호화 된다. 필요한 경우 Terraform은 백 엔드에서 상태를 검색하여 로컬 메모리에 저장한다. 이 패턴을 사용하면 상태는 로컬 디스크에 기록되지 않는다.
Azure Storage 암호화에 대한 자세한 내용은 미사용 데이터에 대한 Azure Storage 서비스 암호화를 참조한다.
'Azure와 함께 하는 DevOps' 카테고리의 다른 글
15 Terraform을 사용하여 Azure Kubernetes Service로 Kubernetes 클러스터 만들기 (0) | 2020.01.20 |
---|---|
14 Terraform을 사용하여 Azure 배포 슬롯으로 인프라 프로비전 (0) | 2020.01.13 |
12 Azure의 Terraform (0) | 2019.12.30 |
11 Azure DevOps 사용하여 ARM 템플릿 CI/CD 파이프라인 구성하기 (0) | 2019.12.23 |
Azure DevOps 계정 만들기 (0) | 2019.12.22 |