Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue in documentation for Deploying Aspire via AZDO #983

Open
joseph-hungerman opened this issue May 27, 2024 · 9 comments
Open

Issue in documentation for Deploying Aspire via AZDO #983

joseph-hungerman opened this issue May 27, 2024 · 9 comments
Labels
⌚ Not Triaged Not triaged

Comments

@joseph-hungerman
Copy link

I am attempting to deploy an Aspire app to Azure. I followed the documentation and everything went as expected until I reached the provisioning step of the Pipeline. I get an error back that says: ERROR: no project exists; to create a new project, run azd init. I ran this command as stated within the documentation, which creates a set of documents that are ignored by the repo. I am assuming this config is set within the connection of the pipeline workflow and creating the pipeline using bicep. I tried running the following pwsh command, but there is a prompt to continue that has no default, so this option didn't work. I then tried exposing the .azure folder to git and that didn't work either. Some help troubleshooting this would be great. I would also expect this to be covered within the documentation.

- pwsh: | azd init --environment $(AZURE_ENV_NAME) --location $(AZURE_LOCATION) --subscription $(AZURE_SUBSCRIPTION_ID) --from-code --no-prompt

@dotnet-bot dotnet-bot added the ⌚ Not Triaged Not triaged label May 27, 2024
@alexwolfmsft
Copy link
Contributor

Hello, if you run azd pipeline config before azd init it does produce the error "no project exists; to create a new project, run azd init".
Did you try to run azd init before you run azd pipeline config after creating a new starter project? To complete the default flow of the tutorial you shouldn't have to run azd init with any parameters.

@joseph-hungerman
Copy link
Author

joseph-hungerman commented May 30, 2024

This isn't for the starter project, this is for a real world project. I have 4 environments (test, dev, stg, ?$?@). My command workflow:

  1. azd init (set environment to Testing during prompt)
    a. This created a bunch of hidden files in the .azure folder with a .gitignore for all of them
    Screenshot 2024-05-30 092520

  2. Created azure-dev.yml as described
    Screenshot 2024-05-30 092641

  3. azd pipeline config --provider azdo (set to my org with PAT)

  4. Pipeline was created in AZDO with variables, resulting file created by azd in AZDO:
    `trigger:

  • feature/*

pool:
vmImage: ubuntu-latest

steps:

  • task: setup-azd@0
    displayName: Install azd

azd delegate auth to az to use service connection with AzureCLI@2

  • pwsh: |
    azd config set auth.useAzCliAuth "true"
    displayName: Configure azd to Use AZ CLI Authentication.

  • task: Bash@3
    displayName: Install .NET Aspire workload
    inputs:
    targetType: 'inline'
    script: |
    dotnet workload install aspire

  • task: AzureCLI@2
    displayName: Provision Infrastructure
    inputs:
    azureSubscription: azconnection
    scriptType: bash
    scriptLocation: inlineScript
    inlineScript: |
    azd provision --no-prompt --no-state --environment $(AZURE_ENV_NAME)
    env:
    AZD_INITIAL_ENVIRONMENT_CONFIG: $(AZD_INITIAL_ENVIRONMENT_CONFIG)
    AZURE_SUBSCRIPTION_ID: $(AZURE_SUBSCRIPTION_ID)
    AZURE_ENV_NAME: $(AZURE_ENV_NAME)
    AZURE_LOCATION: $(AZURE_LOCATION)

  • task: AzureCLI@2
    displayName: Deploy Application
    inputs:
    azureSubscription: azconnection
    scriptType: bash
    scriptLocation: inlineScript
    inlineScript: |
    azd deploy --all --no-prompt --environment Testing
    env:
    AZURE_SUBSCRIPTION_ID: $(AZURE_SUBSCRIPTION_ID)
    AZURE_ENV_NAME: $(AZURE_ENV_NAME)
    AZURE_LOCATION: $(AZURE_LOCATION)
    ASPNETCORE_ENVIRONMENT: $(AZURE_ENV_NAME)`

  1. Ran pipeline.
    /usr/bin/az account set --subscription XXXXXXXXXXXXXXXXXXXXXXXX
    /usr/bin/bash /home/vsts/work/_temp/azureclitaskscript1717079556333.sh

ERROR: no project exists; to create a new project, run azd init
##[error]Script failed with exit code: 1
/usr/bin/az account clear
Finishing: Provision Infrastructure

@joseph-hungerman
Copy link
Author

Another annoyance: AZD_INITIAL_ENVIRONMENT_CONFIG is set to secret when the pipeline is pushed to my project. I can't validate whether anything in this variable is correct. This would be less problematic if it was pushed as a normal var and let the user set it as secret. Once it's a secret it can't be viewed.

@IEvangelist
Copy link
Member

Hey @alexwolfmsft - any chance you could look into this one?

@Moristar
Copy link

I have the same issue. Set everything up with azd init. Created DEV environment and pushing to it successfully with azd up. When development got to the point we wanted to add CI/CD we just faced a wall. Documentation prescribed steps produce a pipeline in our Azure DevOps organization, but when the pipeline is running - it just returns:

Provision infrastructure step
...
/usr/bin/az account set --subscription <Subscription_ID>
/usr/bin/bash /home/vsts/work/_temp/azureclitaskscript1725931063275.sh

ERROR: no project exists; to create a new project, run azd init


I can only assume that developers are not using Azure DevOps themselves and documentation is even contains an image with a sample of the setup command using GitHub actions for Azure DevOps section: https://learn.microsoft.com/en-us/dotnet/aspire/deployment/azure/aca-deployment-github-actions?tabs=windows&pivots=azure-pipelines#create-the-azure-devops-repository-and-pipeline

It's not a "sample app" for some of us. We're trying to get to market fast with a small team, however we're stumbling over smallest things all the time, because Aspire is not treated as an enterprise level solution it seems.

@joseph-hungerman
Copy link
Author

So is no one going to look at this? I put it aside for a while because I was solo so I could just manually deploy, but now I'm building an MVP. I brought on a 20+ year .NET developer / architect and he can't get it to work either. My initial message was almost 6 months ago!

@davidfowl
Copy link
Member

cc @vhvb1989

@vhvb1989
Copy link
Contributor

@joseph-hungerman , since you ran azd init from inside the AppHost folder, the azure.yaml is created there.
Azure.yaml defines where is the azd project root.

On your pipeline, either use the cwd for the step where you are running azd provision or manually cd into your AppFolder before running azd provision.

You are not expected to run azd init on CI/CD

Lmk if this works for you.

(Optionally, you can use the root of your repo to run azd init and then you wouldn't need to cd to the AppHost folder on CI/CD)

@joseph-hungerman
Copy link
Author

joseph-hungerman commented Oct 13, 2024

So moving azure.yaml to the root of the solution worked, after I updated the directory. All of the documentation I have see says to run azd init on the project. So that probably needs to be looked at.

Now I am facing an issue in deploy pulling env vars I have setup in the .env file for the Testing environment. I have all of the files as secure files, and the variables are setup in a group within the library. I have checked and the file is being downloaded to where I expect. Here is my pipeline and the error:

`
trigger:

  • feature/*

pool:
vmImage: ubuntu-latest

variables:
- group: common-publish
- group: tst-publish

steps:

  • task: setup-azd@0
    displayName: Install azd

  • pwsh: |
    azd config set auth.useAzCliAuth "true"
    displayName: Configure AZD to Use AZ CLI Authentication.

  • task: Bash@3
    displayName: Install .NET Aspire workload
    inputs:
    targetType: 'inline'
    script: |
    dotnet workload install aspire

  • task: DownloadSecureFile@1
    name: orgmgmtenv
    displayName: 'Download orgmgmt env variables'
    inputs:
    secureFile: "org.env"

  • task: CopyFiles@2
    displayName: 'Copy OrgMgmt .env'
    inputs:
    SourceFolder: '$(Agent.TempDirectory)'
    TargetFolder: '$(System.DefaultWorkingDirectory)/src/backend/CoreContexts/OrgMgmtApi/src/OrgMgmt.WebHost'
    Contents: '**/*.env'

  • task: DownloadSecureFile@1
    name: leanenv
    displayName: 'Download lean env variables'
    inputs:
    secureFile: "lean.env"

  • task: CopyFiles@2
    displayName: 'Copy Lean .env'
    inputs:
    SourceFolder: '$(Agent.TempDirectory)'
    TargetFolder: '$(System.DefaultWorkingDirectory)/src/backend/ContinuousImprovement/LeanApi/src/LeanApi.WebHost'
    Contents: '**/*.env'

  • task: DownloadSecureFile@1
    name: projenv
    displayName: 'Download proj env variables'
    inputs:
    secureFile: "proj.env"

  • task: CopyFiles@2
    displayName: 'Copy Proj .env'
    inputs:
    SourceFolder: '$(Agent.TempDirectory)'
    TargetFolder: '$(System.DefaultWorkingDirectory)/src/backend/CoreContexts/ProjMgmtApi/src/ProjMgmtApi.WebHost'
    Contents: '**/*.env'

  • task: DownloadSecureFile@1
    name: stkenv
    displayName: 'Download stk env variables'
    inputs:
    secureFile: "stk.env"

  • task: CopyFiles@2
    displayName: 'Copy Stk .env'
    inputs:
    SourceFolder: '$(Agent.TempDirectory)'
    TargetFolder: '$(System.DefaultWorkingDirectory)/src/backend/CoreContexts/StkHldApi/src/StkHldApi.WebHost'
    Contents: '**/*.env'

  • task: DownloadSecureFile@1
    name: uienv
    displayName: 'Download ui env variables'
    inputs:
    secureFile: "app.env"

  • task: CopyFiles@2
    displayName: 'Copy UI .env'
    inputs:
    SourceFolder: '$(Agent.TempDirectory)'
    TargetFolder: '$(System.DefaultWorkingDirectory)/src/frontend/UI/src/UI.Presentation.Server'
    Contents: '**/*.env'

  • task: DownloadSecureFile@1
    name: tstenv
    displayName: 'Download apphost env variables'
    inputs:
    secureFile: "apptst.env"

  • task: CopyFiles@2
    displayName: 'Copy AppHost .env'
    inputs:
    SourceFolder: '$(Agent.TempDirectory)'
    TargetFolder: '$(System.DefaultWorkingDirectory)/src/frontend/UI/src/Orchestration/UI.Presentation.AppHost/.azure/Testing'
    Contents: '**/*.env'

  • task: DownloadSecureFile@1
    name: tstconfig
    displayName: 'Download apphost tst config'
    inputs:
    secureFile: "apptst.config.json"

  • task: CopyFiles@2
    displayName: 'Copy AppHost tst config'
    inputs:
    SourceFolder: '$(Agent.TempDirectory)'
    TargetFolder: '$(System.DefaultWorkingDirectory)/src/frontend/UI/src/Orchestration/UI.Presentation.AppHost/.azure/Testing'
    Contents: '**/*.json'

  • task: DownloadSecureFile@1
    name: hostconfig
    displayName: 'Download apphost config'
    inputs:
    secureFile: "apphost.config.json"

  • task: CopyFiles@2
    displayName: 'Copy AppHost config'
    inputs:
    SourceFolder: '$(Agent.TempDirectory)'
    TargetFolder: '$(System.DefaultWorkingDirectory)/src/frontend/UI/src/Orchestration/UI.Presentation.AppHost/.azure'
    Contents: '**/*.json'

  • task: PowerShell@2
    displayName: 'Rename .env & config files'
    inputs:
    targetType: 'inline'
    script: |
    $paths = @(
    "$(System.DefaultWorkingDirectory)/src/backend/CoreContexts/OrgMgmtApi/src/OrgMgmtApi.WebHost",
    "$(System.DefaultWorkingDirectory)/src/backend/CoreContexts/ProjMgmtApi/src/ProjMgmtApi.WebHost",
    "$(System.DefaultWorkingDirectory)/src/backend/CoreContexts/StkHldApi/src/StkHldApi.WebHost",
    "$(System.DefaultWorkingDirectory)/src/backend/ContinuousImprovement/LeanApi/src/LeanApi.WebHost",
    "$(System.DefaultWorkingDirectory)/src/frontend/UI/src/Orchestration/UI.Presentation.AppHost/.azure/Testing",
    "$(System.DefaultWorkingDirectory)/src/frontend/UI/src/Orchestration/UI.Presentation.AppHost/.azure",
    "$(System.DefaultWorkingDirectory)/src/frontend/UI/src/UI.Presentation.Server"
    )

    foreach ($path in $paths) {
    # Normalize the path to handle any potential issues with slashes
    $normalizedPath = [System.IO.Path]::GetFullPath($path)
    
    # Find all .env files in the directory
    $envFiles = Get-ChildItem -Path $normalizedPath -Filter "*.env"
    $configFiles = Get-ChildItem -Path $normalizedPath -Filter "*config.json"
    
    foreach ($file in $envFiles) {
        $dir = $file.DirectoryName
        $newPath = Join-Path -Path $dir -ChildPath ".env"
    
        # Check if the new .env file already exists
        if (Test-Path -Path $newPath) {
            Write-Host "File already exists: $newPath. Skipping."
        } else {
            Rename-Item -Path $file.FullName -NewName $newPath
            Write-Host "Renamed $($file.FullName) to $newPath"
        }
      }
    
    foreach ($file in $configFiles) {
    $dir = $file.DirectoryName
    $newPath = Join-Path -Path $dir -ChildPath "config.json"
    
    # Check if the new config file already exists
    if (Test-Path -Path $newPath) {
        Write-Host "File already exists: $newPath. Skipping."
    } else {
        Rename-Item -Path $file.FullName -NewName $newPath
        Write-Host "Renamed $($file.FullName) to $newPath"
    }
    }
    }
    

- task: AzureCLI@2

displayName: Provision Infrastructure

inputs:

azureSubscription: azconnection

scriptType: bash

scriptLocation: inlineScript

inlineScript: |

azd provision --no-prompt --environment $(AZURE_ENV_NAME)

env:

AZURE_SUBSCRIPTION_ID: $(AZURE_SUBSCRIPTION_ID)

AZURE_ENV_NAME: $(AZURE_ENV_NAME)

AZURE_LOCATION: $(AZURE_LOCATION)

  • task: AzureCLI@2
    displayName: Deploy Application
    inputs:
    azureSubscription: azconnection
    scriptType: bash
    scriptLocation: inlineScript
    inlineScript: |
    azd deploy --no-prompt --environment $(AZURE_ENV_NAME)
    env:
    AZURE_SUBSCRIPTION_ID: $(AZURE_SUBSCRIPTION_ID)
    AZURE_ENV_NAME: $(AZURE_ENV_NAME)
    AZURE_LOCATION: $(AZURE_LOCATION)
    AZURE_ENV_NAME_LOWER: $(AZURE_ENV_NAME_LOWER)
    `

ERROR: failed deploying service 'cache': failed executing template file: template: manifest template:2:17: executing "manifest template" at <.Env.AZURE_LOCATION>: map has no entry for key "AZURE_LOCATION"

Cache template:

api-version: 2024-02-02-preview location: {{ .Env.AZURE_LOCATION }} identity: type: UserAssigned userAssignedIdentities: ? "{{ .Env.AZURE_CONTAINER_REGISTRY_MANAGED_IDENTITY_ID }}" : {} properties: environmentId: {{ .Env.AZURE_CONTAINER_APPS_ENVIRONMENT_ID }} configuration: activeRevisionsMode: single runtime: dotnet: autoConfigureDataProtection: true ingress: external: false targetPort: 6379 transport: tcp allowInsecure: false registries: - server: {{ .Env.AZURE_CONTAINER_REGISTRY_ENDPOINT }} identity: {{ .Env.AZURE_CONTAINER_REGISTRY_MANAGED_IDENTITY_ID }} template: containers: - image: {{ .Image }} name: cache-{{ .Env.AZURE_ENV_NAME_LOWER }} env: - name: AZURE_CLIENT_ID value: {{ .Env.MANAGED_IDENTITY_CLIENT_ID }} scale: minReplicas: 1 tags: azd-service-name: cache aspire-resource-name: cache

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
⌚ Not Triaged Not triaged
Projects
None yet
Development

No branches or pull requests

7 participants