Share via


자습서: GitHub Actions를 사용하여 Azure Device Provisioning Service 자동화

GitHub Actions 같은 자동화 도구를 사용하여 IoT 디바이스 수명 주기를 관리합니다. 이 자습서에서는 Azure DPS(Device Provisioning Service)를 사용하여 디바이스를 IoT 허브에 연결하는 GitHub Actions 워크플로를 보여 줍니다.

이 자습서에서는 다음을 하는 방법을 알아볼 수 있습니다.

  • 인증 자격 증명을 리포지토리 비밀로 저장합니다.
  • IoT Hub 및 Device Provisioning Service 리소스를 프로비전하는 워크플로를 만듭니다.
  • 워크플로를 실행하고 IoT Hub에 연결할 때 시뮬레이션된 디바이스를 모니터링합니다.

필수 조건

  • Azure 구독

    Azure 구독이 없는 경우 시작하기 전에 체험 계정을 만듭니다.

  • Azure CLI

    • Azure Cloud Shell에서 Bash 환경을 사용합니다.

    • 또는 CLI 참조 명령을 로컬에서 실행하려는 경우 Azure CLI를 설치합니다. Windows 또는 macOS에서 실행 중인 경우 Docker 컨테이너에서 Azure CLI를 실행하는 것이 좋습니다.

      • 로컬 설치를 사용하는 경우 az login 명령을 사용하여 Azure CLI에 로그인합니다.

      • az version을 실행하여 설치된 버전과 종속 라이브러리를 찾습니다. 최신 버전으로 업그레이드하려면 az upgrade를 실행합니다.

  • 소유한 리포지토리 또는 관리자 액세스 권한이 있는 리포지토리가 있는 GitHub 계정. 자세한 내용은 GitHub 시작을 참조하세요.

1 - 리포지토리 비밀 만들기

다음 섹션에서 정의할 워크플로를 사용하려면 Azure 구독에 액세스하여 리소스를 만들고 관리해야 합니다. 해당 정보를 검색할 수 있는 보호되지 않은 파일에 보관하지 않으려면 리포지토리 비밀을 대신 사용하여 이 정보를 저장하되 워크플로에서 환경 변수로 액세스할 수 있도록 합니다. 자세한 내용은 암호화된 비밀을 참조하세요.

리포지토리 소유자와 관리자만 리포지토리 비밀을 관리할 수 있습니다.

서비스 주체 만들기

개인 액세스 자격 증명을 제공하는 대신 서비스 주체를 만든 다음, 해당 자격 증명을 리포지토리 비밀로 추가합니다. 새 서비스 주체를 만들려면 Azure CLI를 사용합니다. 자세한 내용은 Azure 서비스 주체 만들기를 참조하세요.

  1. az ad sp create-for-rbac 명령을 사용하여 특정 리소스 그룹에 대한 기여자 액세스 권한이 있는 서비스 주체를 만듭니다. <SUBSCRIPTION_ID><RESOURCE_GROUP_NAME>를 사용자 고유의 정보로 바꿉니다.

    이 명령을 사용하려면 구독의 소유자 또는 사용자 액세스 관리자 역할이 필요합니다.

    az ad sp create-for-rbac --name github-actions-sp --role contributor --scopes /subscriptions/<SUBSCRIPTION_ID>/resourceGroups/<RESOURCE_GROUP_NAME>
    
  2. 서비스 주체 만들기 명령의 출력에서 다음 섹션에서 사용할 다음 항목을 복사합니다.

    • clientId
    • clientSecret. 다시 액세스할 수 없는 서비스 주체에 대해 생성된 암호입니다.
    • tenantId
  3. az role assignment create 명령을 사용하여 서비스 주체에 Device Provisioning Service 데이터 기여자IoT Hub 데이터 기여자라는 두 개의 액세스 역할을 더 할당합니다. <SP_CLIENT_ID>를 이전 명령의 출력에서 복사한 clientId 값으로 바꿉니다.

    az role assignment create --assignee "<SP_CLIENT_ID>" --role "Device Provisioning Service Data Contributor" --resource-group "<RESOURCE_GROUP_NAME>"
    
    az role assignment create --assignee "<SP_CLIENT_ID>" --role "IoT Hub Data Contributor" --resource-group "<RESOURCE_GROUP_NAME>"
    

서비스 주체 자격 증명을 비밀로 저장

  1. GitHub.com에서 리포지토리의 설정으로 이동합니다.

  2. 탐색 메뉴에서 비밀을 선택한 다음, 작업을 선택합니다.

  3. 새 리포지토리 비밀을 선택합니다.

  4. 서비스 주체 ID의 비밀을 만듭니다.

    • 이름: APP_ID
    • 비밀: 서비스 주체 만들기 명령의 출력에서 복사한 clientId를 붙여넣습니다.
  5. 비밀 추가를 선택한 다음, 새 리포지토리 비밀을 선택하여 두 번째 비밀을 추가합니다.

  6. 서비스 주체 암호의 비밀을 만듭니다.

    • 이름: SECRET
    • 비밀: 서비스 주체 만들기 명령의 출력에서 복사한 clientSecret를 붙여넣습니다.
  7. 비밀 추가를 선택한 다음, 새 리포지토리 비밀을 선택하여 마지막 비밀을 추가합니다.

  8. Azure 테넌트의 비밀을 만듭니다.

    • 이름: TENANT
    • 비밀: 서비스 주체 만들기 명령의 출력에서 복사한 tenantId를 붙여넣습니다.
  9. 비밀 추가를 선택합니다.

2 - 워크플로 만들기

GitHub Actions 워크플로이벤트에 의해 트리거되면 실행될 태스크를 정의합니다. 워크플로는 병렬로 또는 순차적으로 실행될 수 있는 작업을 하나 이상 포함합니다. 자세한 내용은 GitHub Actions 이해를 참조하세요.

이 자습서에서는 다음 각 태스크에 대한 작업을 포함하는 하나의 워크플로를 만듭니다.

  • IoT Hub 인스턴스 및 DPS 인스턴스를 프로비전합니다.
  • IoT Hub 및 DPS 인스턴스를 서로 연결합니다.
  • DPS 인스턴스에 개별 등록을 만들고 DPS 등록을 통해 대칭 키 인증을 사용하여 IoT Hub에 디바이스를 등록합니다.
  • 5분 동안 디바이스를 시뮬레이션하고 IoT 허브 이벤트를 모니터링합니다.

워크플로는 리포지토리의 .github/workflows/ 디렉터리에 있는 YAML 파일입니다.

  1. GitHub 리포지토리에서 작업 탭으로 이동합니다.

  2. 작업 창에서 새 워크플로를 선택합니다.

  3. 워크플로 선택 페이지에서 사용할 미리 빌드된 템플릿을 선택할 수 있습니다. 이 자습서를 위한 자체 워크플로를 만들 것이므로 직접 워크플로 설정을 선택합니다.

  4. GitHub가 사용자를 위해 새 워크플로 파일을 만듭니다. 이 파일은 .github/workflows/ 디렉터리에 있습니다. 새 파일에 dps-tutorial.yml 같은 의미 있는 이름을 지정합니다.

  5. name 매개 변수를 추가하여 워크플로에 이름을 지정합니다.

    name: DPS Tutorial
    
  6. on.workflow_dispatch 매개 변수를 추가합니다. on 매개 변수는 워크플로가 실행되는 시기를 정의합니다. workflow_dispatch 매개 변수는 워크플로를 수동으로 트리거하려고 했음을 나타냅니다. 이 매개 변수를 사용하면 각 실행 시 워크플로에 전달될 inputs를 정의할 수 있지만 이 자습서에는 이를 사용하지 않습니다.

    on: workflow_dispatch
    
  7. 워크플로에서 만들 리소스의 환경 변수를 정의합니다. 이러한 변수는 워크플로의 모든 작업에 사용할 수 있습니다. 개별 작업 또는 작업 내의 개별 단계에 대한 환경 변수를 정의할 수도 있습니다.

    자리 표시자 값을 사용자 고유의 값으로 바꿉니다. 서비스 주체가 액세스할 수 있는 것과 동일한 리소스 그룹을 지정해야 합니다.

    env:
      HUB_NAME: <Globally unique IoT hub name>
      DPS_NAME: <Desired Device Provisioning Service name>
      DEVICE_NAME: <Desired device name>
      RESOURCE_GROUP: <Solution resource group where resources will be created>
    
  8. 이전 섹션에서 만든 비밀에 대한 환경 변수를 정의합니다.

      SP_USER: ${{ secrets.APP_ID }}
      SP_SECRET: ${{ secrets.SECRET }}
      SP_TENANT: ${{ secrets.TENANT }}
    
  9. jobs 매개 변수를 워크플로 파일에 추가합니다.

    jobs:
    
  10. provision 작업을 호출할 워크플로의 첫 번째 작업을 정의합니다. 이 작업은 IoT Hub 및 DPS 인스턴스를 프로비전합니다.

      provision:
        runs-on: ubuntu-latest
        steps:
          - name: Provision Infra
            run: |
              az --version
              az login --service-principal -u "$SP_USER" -p "$SP_SECRET" --tenant "$SP_TENANT"
              az iot hub create -n "$HUB_NAME" -g "$RESOURCE_GROUP"
              az iot dps create -n "$DPS_NAME" -g "$RESOURCE_GROUP"
    

    이 작업에서 실행되는 명령에 대한 자세한 내용은 다음을 참조하세요.

  11. DPS 및 IoT Hub 인스턴스 configure에 대한 작업을 정의합니다. 이 작업은 needs 매개 변수를 사용합니다. 즉, 나열된 작업이 자체 실행을 성공적으로 완료할 때까지 configure 작업이 실행되지 않습니다.

      configure:
        runs-on: ubuntu-latest
        needs: provision
        steps:
          - name: Configure Infra
            run: |
              az login --service-principal -u "$SP_USER" -p "$SP_SECRET" --tenant "$SP_TENANT"
              az iot dps linked-hub create --dps-name "$DPS_NAME" --hub-name "$HUB_NAME"   
    

    이 작업에서 실행되는 명령에 대한 자세한 내용은 다음을 참조하세요.

  12. 개별 등록을 만든 다음, 해당 등록을 사용하여 IoT Hub에 디바이스를 등록하는 register라는 작업을 정의합니다.

      register:
        runs-on: ubuntu-latest
        needs: configure
        steps:
          - name: Create enrollment
            run: |
              az login --service-principal -u "$SP_USER" -p "$SP_SECRET" --tenant "$SP_TENANT"
              az extension add --name azure-iot
              az iot dps enrollment create -n "$DPS_NAME" --eid "$DEVICE_NAME" --attestation-type symmetrickey --auth-type login
          - name: Register device
            run: |
              az iot device registration create -n "$DPS_NAME" --rid "$DEVICE_NAME" --auth-type login   
    

    참고 항목

    이 작업 및 다른 작업은 일부 명령에서 --auth-type login 매개 변수를 사용하여 작업이 현재 Microsoft Entra 세션의 서비스 주체를 사용해야 함을 나타냅니다. 대안인 --auth-type key의 경우 서비스 주체 구성이 필요하지 않지만 보안은 떨어집니다.

    이 작업에서 실행되는 명령에 대한 자세한 내용은 다음을 참조하세요.

  13. IoT Hub에 연결하고 샘플 원격 분석 메시지를 보낼 IoT 디바이스 simulate에 대한 작업을 정의합니다.

      simulate:
        runs-on: ubuntu-latest
        needs: register
        steps:
          - name: Simulate device
            run: |
              az login --service-principal -u "$SP_USER" -p "$SP_SECRET" --tenant "$SP_TENANT"
              az extension add --name azure-iot
              az iot device simulate -n "$HUB_NAME" -d "$DEVICE_NAME"
    

    이 작업에서 실행되는 명령에 대한 자세한 내용은 다음을 참조하세요.

  14. 이벤트의 IoT 허브 엔드포인트 monitor에 대한 작업을 정의하고 시뮬레이션된 디바이스에서 들어오는 메시지를 감시합니다. simulatemonitor 작업은 모두 needs 매개 변수에 register 작업을 정의합니다. 이 구성은 register 작업이 성공적으로 완료되면 이러한 작업이 병렬로 실행됨을 의미합니다.

      monitor:
        runs-on: ubuntu-latest
        needs: register
        steps:
          - name: Monitor d2c telemetry
            run: |
              az login --service-principal -u "$SP_USER" -p "$SP_SECRET" --tenant "$SP_TENANT"
              az extension add --name azure-iot
              az iot hub monitor-events -n "$HUB_NAME" -y   
    

    이 작업에서 실행되는 명령에 대한 자세한 내용은 다음을 참조하세요.

  15. 전체 워크플로 파일은 환경 변수의 자리 표시자 값을 대체하는 정보가 포함된 다음 예제와 같습니다.

    name: DPS Tutorial
    
    on: workflow_dispatch
    
    env:
      HUB_NAME: <Globally unique IoT hub name>
      DPS_NAME: <Desired Device Provisioning Service name>
      DEVICE_NAME: <Desired device name>
      RESOURCE_GROUP: <Solution resource group where resources will be created>
      SP_USER: ${{ secrets.APP_ID }}
      SP_SECRET: ${{ secrets.SECRET }}
      SP_TENANT: ${{ secrets.TENANT }}
    
    jobs:
      provision:
        runs-on: ubuntu-latest
        steps:
          - name: Provision Infra
            run: |
              az --version
              az login --service-principal -u "$SP_USER" -p "$SP_SECRET" --tenant "$SP_TENANT"
              az iot hub create -n "$HUB_NAME" -g "$RESOURCE_GROUP"
              az iot dps create -n "$DPS_NAME" -g "$RESOURCE_GROUP"
      configure:
        runs-on: ubuntu-latest
        needs: provision
        steps:
          - name: Configure Infra
            run: |
              az login --service-principal -u "$SP_USER" -p "$SP_SECRET" --tenant "$SP_TENANT"
              az iot dps linked-hub create --dps-name "$DPS_NAME" --hub-name "$HUB_NAME"
      register:
        runs-on: ubuntu-latest
        needs: configure
        steps:
          - name: Create enrollment
            run: |
              az login --service-principal -u "$SP_USER" -p "$SP_SECRET" --tenant "$SP_TENANT"
              az extension add --name azure-iot
              az iot dps enrollment create -n "$DPS_NAME" --eid "$DEVICE_NAME" --attestation-type symmetrickey --auth-type login
          - name: Register device
            run: |
              az iot device registration create -n "$DPS_NAME" --rid "$DEVICE_NAME" --auth-type login
      simulate:
        runs-on: ubuntu-latest
        needs: register
        steps:
          - name: Simulate device
            run: |
              az login --service-principal -u "$SP_USER" -p "$SP_SECRET" --tenant "$SP_TENANT"
              az extension add --name azure-iot
              az iot device simulate -n "$HUB_NAME" -d "$DEVICE_NAME"
      monitor:
        runs-on: ubuntu-latest
        needs: register
        steps:
          - name: Monitor d2c telemetry
            run: |
              az login --service-principal -u "$SP_USER" -p "$SP_SECRET" --tenant "$SP_TENANT"
              az extension add --name azure-iot
              az iot hub monitor-events -n "$HUB_NAME" -y
    
  16. 이 새 파일을 GitHub 리포지토리에 저장, 커밋하고 푸시합니다.

3 - 워크플로 실행

  1. GitHub 리포지토리의 작업 탭으로 이동합니다.

  2. 작업 창에서 워크플로 파일에 정의한 이름인 DPS 자습서를 선택한 다음, 워크플로 실행 드롭다운 상자를 선택합니다.

    Screenshot of the action tab where you can select a workflow and run it.

  3. 기본 이외의 분기에서 워크플로를 만든 경우 분기를 변경한 다음, 워크플로 실행을 선택합니다.

  4. 새 워크플로 실행이 진행 중으로 표시됩니다. 이름을 선택하여 실행의 세부 정보를 봅니다.

  5. 워크플로 요약에서 각 작업이 시작되고 완료되는 것을 감시할 수 있습니다. 작업 이름을 선택하여 작업 세부 정보를 봅니다. 시뮬레이션된 디바이스 작업은 5분 동안 실행되고 IoT Hub에 원격 분석을 보냅니다. 이 시간 동안 디바이스에서 보내는 메시지를 감시하려면 simulate 작업을 선택하고, IoT Hub에 수신되는 메시지를 감시하려면 monitor 작업을 선택합니다.

  6. 모든 작업이 성공적으로 완료되면 각 작업별로 녹색 확인 표시가 표시됩니다.

    Screenshot of a successfully completed workflow.

리소스 정리

이 자습서에서 생성된 이러한 리소스를 더 이상 사용하지 않으려면 다음 단계에 따라 삭제합니다.

Azure CLI 사용:

  1. 리소스 그룹의 리소스를 나열합니다.

    az resource list --resource-group <RESOURCE_GROUP_NAME>
    
  2. 개별 리소스를 삭제하려면 리소스 ID를 사용합니다.

    az resource delete --resource-group <RESOURCE_GROUP_NAME> --ids <RESOURCE_ID>
    
  3. 전체 리소스 그룹 및 그 안의 모든 리소스를 삭제하려면 다음 명령을 실행합니다.

    az group delete --resource-group <RESOURCE_GROUP_NAME>
    

Azure Portal 사용:

  1. Azure Portal에서 새 리소스를 만든 리소스 그룹으로 이동합니다.
  2. 전체 리소스 그룹을 삭제하거나 제거할 개별 리소스를 선택한 다음, 삭제를 선택할 수 있습니다.

다음 단계

다른 자동화 도구를 사용하여 DPS 인스턴스를 프로비전하는 방법을 알아봅니다.