App Service 및 Azure Functions의 App Configuration 참조 사용(미리 보기)

이 항목에서는 코드 변경 없이도 App Service 또는 Azure Functions 애플리케이션에서 구성 데이터로 작업하는 방법을 보여줍니다. Azure App Configuration은 애플리케이션 구성을 중앙에서 관리하는 서비스입니다. 또한 시간 또는 릴리스에 따른 구성 값에 대한 효과적인 감사 도구입니다.

앱에 App Configuration에 대한 액세스 권한 부여

App Service에서 App Configuration 참조 사용을 시작하려면 먼저 App Configuration 저장소가 필요하고 스토어의 구성 키-값에 액세스할 수 있는 앱 권한을 제공합니다.

  1. 앱App Configuration 빠른 시작에 따라 App Configuration 저장소를 만듭니다.

    참고 항목

    App Configuration 참조는 네트워크 제한 구성 저장소를 아직 지원하지 않습니다.

  2. 애플리케이션에 대한 관리 ID를 만듭니다.

    App Configuration 참조는 기본적으로 앱의 시스템 할당 ID를 사용하지만 사용자가 할당한 ID를 지정할 수 있습니다.

  3. 새로 만든 ID가 App Configuration 저장소에 대한 올바른 액세스 권한 집합을 갖도록 설정합니다. 저장소에 대한 역할 할당을 업데이트합니다. 리소스에 대해 범위가 지정된 이 ID에 App Configuration Data Reader 역할을 할당합니다.

사용자가 할당한 ID를 사용하여 App Configuration 저장소에 액세스

일부 앱은 시스템 할당 ID를 아직 사용할 수 없는 경우 생성 시 구성을 참조해야 할 수도 있습니다. 이러한 경우 사용자가 할당한 ID를 만들고 App Configuration 저장소에 대한 액세스 권한을 미리 부여할 수 있습니다. 다음 단계에 따라 App Configuration 저장소에 대한 사용자 할당 ID를 만듭니다.

사용자가 할당한 ID에 대한 사용 권한을 부여한 후에는 다음 단계를 수행합니다.

  1. 아직 없는 경우 애플리케이션에 ID를 할당합니다.

  2. keyVaultReferenceIdentity 속성을 사용자가 할당한 ID의 리소스 ID로 설정하여 App Configuration 참조 작업에 이 ID를 사용하도록 앱을 구성합니다. 속성 이름에 keyVault가 있지만 ID는 App Configuration 참조에도 적용됩니다.

    userAssignedIdentityResourceId=$(az identity show -g MyResourceGroupName -n MyUserAssignedIdentityName --query id -o tsv)
    appResourceId=$(az webapp show -g MyResourceGroupName -n MyAppName --query id -o tsv)
    az rest --method PATCH --uri "${appResourceId}?api-version=2021-01-01" --body "{'properties':{'keyVaultReferenceIdentity':'${userAssignedIdentityResourceId}'}}"
    

이 구성은 이 앱의 모든 참조에 적용됩니다.

참조된 키 자격 증명 모음에 대한 앱 액세스 권한 부여

원시 구성 값을 저장하는 것 외에도 Azure App Configuration에는 Key Vault 참조를 저장하기 위한 고유한 형식이 있습니다. App Configuration 참조 값이 App Configuration 저장소의 Key Vault 참조인 경우 앱에 지정되는 키 자격 증명 모음에 액세스할 수 있는 권한도 있어야 합니다.

참고 항목

Azure App Configuration Key Vault 참조 개념App Service 및 Azure Functions Key Vault 참조 개념과 혼동해서는 안 됩니다. 앱에서 이러한 조합을 사용할 수 있지만 몇 가지 중요한 차이점이 있습니다. 자격 증명 모음을 네트워크로 제한해야 하거나 앱을 정기적으로 최신 버전으로 업데이트해야 하는 경우 App Configuration 참조를 사용하는 대신 App Service 및 Azure Functions 직접 접근 방식을 사용하는 것이 좋습니다.

  1. App Configuration 참조에 사용한 ID를 식별합니다. 자격 증명 모음에 대한 액세스 권한은 동일한 ID에 부여되어야 합니다.

  2. 해당 ID에 대한 Key Vault의 액세스 정책을 만듭니다. 이 정책에 대한 “가져오기” 비밀 권한을 사용하도록 설정합니다. "권한 있는 애플리케이션" 또는 applicationId 설정은 관리 ID와 호환되지 않으므로 구성하지 마세요.

참조 구문

App Configuration 참조는 @Microsoft.AppConfiguration({referenceString}) 형식이며 여기서 {referenceString}은 아래와 같이 대체됩니다.

참조 문자열 부분 설명
엔드포인트=endpoint; 엔드포인트는 참조 문자열의 필수 부분입니다. 엔드포인트 값에는 App Configuration 리소스의 URL이 있어야 합니다.
키=keyName; 는 참조 문자열의 필수 부분을 형성합니다. 의 값은 앱 설정에 할당하려는 키의 이름이어야 합니다.
레이블=label 레이블 부분은 참조 문자열에서 선택 사항입니다. 레이블에 지정된 키에 대한 레이블 값이어야 합니다.

예를 들어, Label이 있는 완전한 참조는 다음과 같습니다.

@Microsoft.AppConfiguration(Endpoint=https://myAppConfigStore.azconfig.io; Key=myAppConfigKey; Label=myKeysLabel)​

또는 Label이 없는 경우는 다음과 같습니다.

@Microsoft.AppConfiguration(Endpoint=https://myAppConfigStore.azconfig.io; Key=myAppConfigKey)​

사이트를 다시 시작하는 앱 구성 변경은 App Configuration 저장소에서 참조된 모든 키-값을 즉시 다시 가져옵니다.

참고 항목

App Configuration에서 키-값이 업데이트된 경우 이러한 값의 자동 새로 고침/다시 페치는 현재 지원되지 않습니다.

앱 구성의 원본 애플리케이션 설정

App Configuration 참조를 애플리케이션 설정의 값으로 사용하면 사이트 구성 대신 App Configuration에 구성 데이터를 유지할 수 있습니다. 애플리케이션 설정 및 App Configuration 키-값은 모두 미사용 시 안전하게 암호화됩니다. 중앙 집중식 구성 관리 기능이 필요한 경우 구성 데이터는 App Config로 이동해야 합니다.

앱 설정에 App Configuration 참조를 사용하려면 참조를 설정 값으로 설정합니다. 앱은 평소와 같이 키를 통해 구성 값을 참조할 수 있습니다. 코드 변경은 필요하지 않습니다.

App Configuration 참조를 사용하는 대부분의 애플리케이션 설정은 각 환경에 대해 별도의 저장소 또는 레이블이 있어야 하므로 슬롯 설정으로 표시되어야 합니다.

Azure Files 탑재 시 고려 사항

앱은 WEBSITE_CONTENTAZUREFILECONNECTIONSTRING 애플리케이션 설정을 사용하여 Azure Files를 파일 시스템으로 탑재할 수 있습니다. 이 설정에는 앱이 제대로 시작될 수 있는지 확인하기 위한 추가 유효성 검사가 포함되어 있습니다. 플랫폼은 Azure Files 내에서 콘텐츠 공유에 따라 달라지며 WEBSITE_CONTENTSHARE 설정을 통해 지정되지 않는 한 기본 이름을 사용합니다. 이러한 설정을 수정하는 모든 요청에 대해 플랫폼은 이 콘텐츠 공유가 있는지 확인하고, 없으면 만들려고 시도합니다. 콘텐츠 공유를 찾거나 만들 수 없으면 요청이 차단됩니다.

이 설정에 대해 App Configuration 참조를 사용하는 경우 들어오는 요청을 처리하는 동안 연결 자체를 확인할 수 없기 때문에 이 유효성 검사는 기본적으로 실패합니다. 이 문제를 방지하려면 WEBSITE_SKIP_CONTENTSHARE_VALIDATION를 "1"로 설정하여 유효성 검사를 건너뛸 수 있습니다. 이 설정은 모든 검사를 건너뛰고 콘텐츠 공유가 생성되지 않습니다. 생성되었는지 미리 확인해야 합니다.

주의

유효성 검사를 건너뛰고 연결 문자열 또는 콘텐츠 공유가 유효하지 않으면 앱이 제대로 시작되지 않고 HTTP 500 오류만 제공됩니다.

사이트를 만드는 과정에서 전파되지 않은 관리 ID 권한 또는 설정되지 않은 가상 네트워크 통합으로 인해 콘텐츠 공유 탑재 시도가 실패할 수도 있습니다. 배포 템플릿에서 나중에 필요한 설정을 수용할 때까지 Azure Files 설정을 연기할 수 있습니다. 자세한 내용은 Azure Resource Manager 배포를 참조하세요. App Service는 Azure Files가 설정될 때까지 기본 파일 시스템을 사용하고 파일은 복사되지 않으므로 Azure Files를 탑재하기 전에 중간 기간 동안 배포 시도가 발생하지 않도록 해야 합니다.

Azure Resource Manager 배포

Azure Resource Manager 템플릿을 통해 리소스 배포를 자동화할 때 이 기능이 작동하려면 종속성을 특정 순서로 시퀀스해야 할 수 있습니다. 중요한 것은, 사이트 정의에서 siteConfig 속성을 사용하는 대신 애플리케이션 설정을 자체 리소스로 정의해야 합니다. 이는 사이트를 먼저 정의해야 사이트를 사용하여 시스템 할당 ID를 만들고 액세스 정책에서 사용할 수 있기 때문입니다.

다음은 App Configuration 참조가 있는 함수 앱에 대한 의사 템플릿의 예입니다.

{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "roleNameGuid": {
            "type": "string",
            "defaultValue": "[newGuid()]",
            "metadata": {
                "description": "A new GUID used to identify the role assignment"
            }
        }
    },
    "variables": {
        "functionAppName": "DemoMBFunc",
        "appConfigStoreName": "DemoMBAppConfig",
        "resourcesRegion": "West US2",
        "appConfigSku": "standard",
        "FontNameKey": "FontName",
        "FontColorKey": "FontColor",
        "myLabel": "Test",
        "App Configuration Data Reader": "[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/', '516239f1-63e1-4d78-a4de-a74fb236a071')]"
    },
    "resources": [
        {
            "type": "Microsoft.Web/sites",
            "name": "[variables('functionAppName')]",
            "apiVersion": "2021-03-01",
            "location": "[variables('resourcesRegion')]",
            "identity": {
                "type": "SystemAssigned"
            },
            //...
            "resources": [
                {
                    "type": "config",
                    "name": "appsettings",
                    "apiVersion": "2021-03-01",
                    //...
                    "dependsOn": [
                        "[resourceId('Microsoft.Web/sites', variables('functionAppName'))]",
                        "[resourceId('Microsoft.AppConfiguration/configurationStores', variables('appConfigStoreName'))]"
                    ],
                    "properties": {
                        "WEBSITE_FONTNAME": "[concat('@Microsoft.AppConfiguration(Endpoint=', reference(resourceId('Microsoft.AppConfiguration/configurationStores', variables('appConfigStoreName'))).endpoint,'; Key=',variables('FontNameKey'),'; Label=',variables('myLabel'), ')')]",
                        "WEBSITE_FONTCOLOR": "[concat('@Microsoft.AppConfiguration(Endpoint=', reference(resourceId('Microsoft.AppConfiguration/configurationStores', variables('appConfigStoreName'))).endpoint,'; Key=',variables('FontColorKey'),'; Label=',variables('myLabel'), ')')]",
                        "WEBSITE_ENABLE_SYNC_UPDATE_SITE": "true"
                        //...
                    }
                },
                {
                    "type": "sourcecontrols",
                    "name": "web",
                    "apiVersion": "2021-03-01",
                    //...
                    "dependsOn": [
                        "[resourceId('Microsoft.Web/sites', variables('functionAppName'))]",
                        "[resourceId('Microsoft.Web/sites/config', variables('functionAppName'), 'appsettings')]"
                    ]
                }
            ]
        },
        {
            "type": "Microsoft.AppConfiguration/configurationStores",
            "name": "[variables('appConfigStoreName')]",
            "apiVersion": "2019-10-01",
            "location": "[variables('resourcesRegion')]",
            "sku": {
                "name": "[variables('appConfigSku')]"
            },
            //...
            "dependsOn": [
                "[resourceId('Microsoft.Web/sites', variables('functionAppName'))]"
            ],
            "properties": {
            },
            "resources": [
                {
                    "type": "keyValues",
                    "name": "[variables('FontNameKey')]",
                    "apiVersion": "2021-10-01-preview",
                    //...
                    "dependsOn": [
                        "[resourceId('Microsoft.AppConfiguration/configurationStores', variables('appConfigStoreName'))]"

                    ],
                    "properties": {
                        "value": "Calibri",
                        "contentType": "application/json"
                    }
                },
                {
                    "type": "keyValues",
                    "name": "[variables('FontColorKey')]",
                    "apiVersion": "2021-10-01-preview",
                    //...
                    "dependsOn": [
                        "[resourceId('Microsoft.AppConfiguration/configurationStores', variables('appConfigStoreName'))]"

                    ],
                    "properties": {
                        "value": "Blue",
                        "contentType": "application/json"
                    }
                }
            ]
        },
        {
            "scope": "[resourceId('Microsoft.AppConfiguration/configurationStores', variables('appConfigStoreName'))]",
            "type": "Microsoft.Authorization/roleAssignments",
            "apiVersion": "2020-04-01-preview",
            "name": "[parameters('roleNameGuid')]",
            "properties": {
                "roleDefinitionId": "[variables('App Configuration Data Reader')]",
                "principalId": "[reference(resourceId('Microsoft.Web/sites/', variables('functionAppName')), '2020-12-01', 'Full').identity.principalId]",
                "principalType": "ServicePrincipal"
            }
        }
    ]
}

참고 항목

이 예제에서 원본 제어 배포는 애플리케이션 설정에 따라 다릅니다. 일반적으로 앱 설정 업데이트는 비동기적으로 동작하므로 안전하지 않은 동작입니다. 그러나 WEBSITE_ENABLE_SYNC_UPDATE_SITE 애플리케이션 설정을 포함했으므로 업데이트가 동기적입니다. 이는 애플리케이션 설정이 완전히 업데이트된 후에만 원본 제어 배포가 시작됨을 의미합니다. 더 많은 앱 설정은 Azure App Service에서 환경 변수 및 앱 설정을 참조하세요.

App Configuration 참조 문제 해결

참조가 제대로 확인되지 않으면 참조 값이 대신 사용됩니다. 애플리케이션 설정의 경우 값이 @Microsoft.AppConfiguration(...) 구문을 갖는 환경 변수가 만들어집니다. 애플리케이션이 대신 구성 값을 예상했기 때문에 오류가 발생할 수 있습니다.

가장 일반적으로 이 오류는 App Configuration 액세스 정책의 잘못된 구성 때문일 수 있습니다. 그러나 참조의 구문 오류 또는 저장소에 존재하지 않는 구성 키-값 때문일 수도 있습니다.

다음 단계