You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: _posts/en/2025-02-04-authentication-backstage-entra-id.md
+17-9Lines changed: 17 additions & 9 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -28,9 +28,11 @@ Since I found it difficult to locate online resources on authentication with Ent
28
28
According to their official [description](https://backstage.io/docs/overview/what-is-backstage/):
29
29
30
30
> *[Backstage](https://backstage.io/) is an open-source framework for building developer portals. Powered by a centralized software catalog, Backstage restores order to your microservices and infrastructure and enables your product teams to ship high-quality code quickly — without compromising autonomy.*
31
-
> *Backstage unifies all your infrastructure tooling, services, and documentation to create a streamlined development environment from end to end.*
31
+
> *Backstage unifies all your infrastructure tooling, services, and documentation to create a streamlined development environment from end to end.*
32
+
---
32
33
33
-
💡 **Note:** Backstage is entirely **developer-focused**. If you, like me, come from an infrastructure background, you may find it challenging since all configurations are done through system files — there is no admin interface for managing users, permissions, integrations, or plugins.
34
+
> **Note:** Backstage is entirely **developer-focused**. If you, like me, come from an infrastructure background, you may find it challenging since all configurations are done through system files — there is no admin interface for managing users, permissions, integrations, or plugins.
35
+
{: .prompt-info }
34
36
35
37
---
36
38
@@ -52,7 +54,8 @@ You can then access Backstage locally at `http://localhost:3000`, signing in as
52
54

53
55
*Guest home page*
54
56
55
-
💡 **Guest access is meant for development purposes only and is not recommended for production.** However, if you still want to enable full guest access, you can find the documentation [here](https://backstage.io/docs/auth/guest/provider/).
57
+
> **Guest access is meant for development purposes only and is not recommended for production.** However, if you still want to enable full guest access, you can find the documentation [here](https://backstage.io/docs/auth/guest/provider/).
58
+
{: .prompt-info }
56
59
57
60
---
58
61
@@ -109,10 +112,12 @@ auth:
109
112
- resolver: userIdMatchingUserEntityAnnotation
110
113
```
111
114
112
-
📌 The values for `clientId`, `tenantId`, and `domainHint` can be found on the **Overview** page of your App Registration in Entra ID.
113
-
📌 The `clientSecret` is created under **Certificates & Secrets**.
114
-
115
-
⚠️ **Security Warning:** Never store `clientSecret` directly in the code. Use **environment variables** for production environments.
115
+
> 📌 The values for `clientId`, `tenantId`, and `domainHint` can be found on the **Overview** page of your App Registration in Entra ID.
116
+
> 📌 The `clientSecret` is created under **Certificates & Secrets**.
117
+
{: .prompt-tip }
118
+
---
119
+
> **Security Warning:** Never store `clientSecret` directly in the code. Use **environment variables** for production environments.
120
+
{: .prompt-warning }
116
121
117
122

118
123
*clientId, tenantId and domainHint*
@@ -186,7 +191,8 @@ const app = createApp({
186
191
187
192
Once this is done, you should see the **Microsoft login button** on the Backstage UI.
188
193
189
-
🚨 However, authentication will fail at this point because Backstage does not recognize the user in its catalog. This leads us to the next step.
194
+
> However, authentication will fail at this point because Backstage does not recognize the user in its catalog. This leads us to the next step.
Copy file name to clipboardExpand all lines: _posts/en/2025-03-05-integrating-backstage-azure-devops.md
+14-9Lines changed: 14 additions & 9 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -36,11 +36,13 @@ I'll keep a repository on my GitHub with the Backstage code resulting from these
36
36
9.[Final Test](#final-test)
37
37
10.[Conclusion](#conclusion)
38
38
39
-
💡 **Note**: Having Entra ID as an IDP is not a prerequisite for working with Azure DevOps. However, it is common for both solutions to be used in a Microsoft environment.
39
+
> **Note**: Having Entra ID as an IDP is not a prerequisite for working with Azure DevOps. However, it is common for both solutions to be used in a Microsoft environment.
40
+
{: .prompt-tip }
40
41
41
42
For this post, I created a new project in Azure DevOps called Backstage, where we will store our Backstage template, Terraform code, and the yaml file to create our pipeline.
42
43
43
-
⚠️ **Attention**: I will assume that you already know how to create a project, repository, and use the minimum necessary git commands.
44
+
> **Attention**: I will assume that you already know how to create a project, repository, and use the minimum necessary git commands.
45
+
{: .prompt-warning}
44
46
45
47
[In this link](https://backstage.io/docs/integrations/azure/locations) you can check the Backstage documentation for this integration. Backstage supports the use of managed identity, service principal, and PAT. For the purpose of this post, I will use PAT as it is simpler.
46
48
@@ -239,11 +241,12 @@ spec:
239
241
entityRef: {% raw %}${{ steps.register.output.entityRef }}{% endraw %}
240
242
```
241
243
242
-
> ⚠️**Important Note about Templates**⚠️:
243
-
>
244
-
> When using relative paths for file handling in Backstage, it **always** starts from the location where **the template was imported**.
245
-
>
246
-
> In other words, it always concatenates the path you provide with the path from where the template was imported. Thus, either you keep the files to be handled in the same location as the file from which you imported the template or use a URL from an external location, which is the approach I used here in the `fetch:template` action. More about this can be seen [here](https://backstage.io/docs/features/software-templates/) and [here](https://backstage.io/docs/tooling/cli/templates/).
244
+
> **Important Note about Templates**:
245
+
246
+
When using relative paths for file handling in Backstage, it **always** starts from the location where **the template was imported**.
247
+
248
+
In other words, it always concatenates the path you provide with the path from where the template was imported. Thus, either you keep the files to be handled in the same location as the file from which you imported the template or use a URL from an external location, which is the approach I used here in the `fetch:template` action. More about this can be seen [here](https://backstage.io/docs/features/software-templates/) and [here](https://backstage.io/docs/tooling/cli/templates/).
249
+
{: .prompt-warning }
247
250
248
251
Returning to our process, create the template file in Azure DevOps (replacing the necessary fields) and then go to Backstage and follow the same import process we did before in the integration test. When importing the template, you might encounter the error below:
⚠️ I am not using a storage account here to store your Terraform state! For production environments, I suggest storing the state in a secure location.
282
+
> I am not using a storage account here to store your Terraform state! For production environments, I suggest storing the state in a secure location.
283
+
{: .prompt-tip }
280
284
281
285
Pay attention to the `name` variable, as it will be filled with the value coming from Backstage. Here we are making a very simple example using only one variable, but extrapolate this idea to any code you want to execute.
282
286
283
287
Once the Terraform code is created, upload it to our Azure DevOps repository.
284
288
285
-
💡 **Important**: since the idea is for Backstage to handle this file and then upload it and subsequently create a Pull Request of code, this (containing the `name` variable) will be replaced by the value coming from Backstage, making the code **non-reusable**.
289
+
> **Important**: since the idea is for Backstage to handle this file and then upload it and subsequently create a Pull Request of code, this (containing the `name` variable) will be replaced by the value coming from Backstage, making the code **non-reusable**.
286
290
To avoid this, we will separate the code with the variable, which we will call `base`, from the code that will have the variable filled, which we will call `changed`, for simplicity. This way, we will always have a place with the code ready to be used.
291
+
{: .prompt-info }
287
292
288
293
Below is the approach I find the simplest, but feel free to adapt it to your needs:
Copy file name to clipboardExpand all lines: _posts/pt-BR/2025-02-04-authentication-backstage-entra-id.md
+17-12Lines changed: 17 additions & 12 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -28,9 +28,11 @@ Como tive dificuldades para encontrar recursos sobre autenticação com o Entra
28
28
De acordo com sua [descrição](https://backstage.io/docs/overview/what-is-backstage) oficial:
29
29
30
30
> *[Backstage](https://backstage.io/) é uma estrutura de código aberto para construção de portais de desenvolvedores. Alimentado por um catálogo de software centralizado, o Backstage restaura a ordem de seus microsserviços e infraestrutura e permite que suas equipes de produto enviem códigos de alta qualidade rapidamente, sem comprometer a autonomia.*
31
-
> *Backstage unifica todas as ferramentas, serviços e documentação de sua infraestrutura para criar um ambiente de desenvolvimento simplificado de ponta a ponta.*
31
+
> *Backstage unifica todas as ferramentas, serviços e documentação de sua infraestrutura para criar um ambiente de desenvolvimento simplificado de ponta a ponta.*
32
+
---
32
33
33
-
💡 **Nota:** Backstage é totalmente **focado em desenvolvedores**. Se você, assim como eu, vem da área de infraestrutura, pode estranhar o fato de que toda a configuração é feita via arquivos de sistema—não há uma interface administrativa para gerenciar usuários, permissões, integrações ou plugins.
34
+
> **Nota:** O Backstage é totalmente **focado em desenvolvedores**. Se você, assim como eu, vem da área de infraestrutura, pode estranhar o fato de que toda a configuração é feita via arquivos de sistema—não há uma interface administrativa para gerenciar usuários, permissões, integrações ou plugins.
35
+
{: .prompt-info }
34
36
35
37
---
36
38
@@ -52,8 +54,8 @@ Você pode então acessar o Backstage localmente em `http://localhost:3000`, ent
52
54

53
55
*Página inicial de convidado*
54
56
55
-
💡**O acesso de convidado é destinado apenas para desenvolvimento e não é recomendado para produção.** No entanto, se desejar habilitá-lo, consulte a documentação [aqui](https://backstage.io/docs/auth/guest/provider/).
56
-
57
+
>**O acesso de convidado é destinado apenas para desenvolvimento e não é recomendado para produção.** No entanto, se desejar habilitá-lo, consulte a documentação [aqui](https://backstage.io/docs/auth/guest/provider/).
58
+
{: .prompt-info }
57
59
---
58
60
59
61
## Passo 2: Criar um App Registration no Entra ID
@@ -110,10 +112,12 @@ auth:
110
112
- resolver: userIdMatchingUserEntityAnnotation
111
113
```
112
114
113
-
📌 Os valores para `clientId`, `tenantId` e `domainHint` podem ser encontrados na **página Overview** do seu App Registration no Entra ID.
114
-
📌 O `clientSecret` é gerado na seção **Certificates & Secrets**.
115
-
116
-
⚠️ **Aviso de Segurança:** Nunca armazene `clientSecret` diretamente no código. Utilize **variáveis de ambiente** em produção.
115
+
> 📌 Os valores para `clientId`, `tenantId` e `domainHint` podem ser encontrados na **página Overview** do seu App Registration no Entra ID.
116
+
> 📌 O `clientSecret` é gerado na seção **Certificates & Secrets**.
117
+
{: .prompt-tip }
118
+
---
119
+
> **Aviso de Segurança:** Nunca armazene `clientSecret` diretamente no código. Utilize **variáveis de ambiente** em produção.
120
+
{: .prompt-warning }
117
121
118
122

119
123
*clientId, tenantId e domainHint*
@@ -187,7 +191,8 @@ const app = createApp({
187
191
188
192
Com isto feito já é possível ver que o botão de autenticação via Entra ID está disponível na interface.
189
193
190
-
🚨 Contudo, a autenticação falhará, pois o Backstage não é capaz de reconhecer o usuário no catálogo. Isso nos leva ao próximo passo.
194
+
> Contudo, a autenticação falhará, pois o Backstage não é capaz de reconhecer o usuário no catálogo. Isso nos leva ao próximo passo.
195
+
{: .prompt-danger }
191
196
192
197

193
198
*Erro de autenticação*
@@ -218,14 +223,14 @@ spec:
218
223
- guests
219
224
```
220
225
226
+
>
221
227
📌 Notas:
222
-
228
+
>
223
229
- `metadata.name`: é o valor de `Mail nickname`, ou o valor antes de `@seudominio.com`;
224
230
- `metadata.annotations.graph.microsoft.com/user-id`: é o valor de `Object ID`;
Copy file name to clipboardExpand all lines: _posts/pt-BR/2025-03-05-integrating-backstage-azure-devops.md
+14-9Lines changed: 14 additions & 9 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -36,11 +36,13 @@ Eu vou manter no meu GitHub um repositório do Backstage com o resultado destes
36
36
9.[Teste final](#teste-final)
37
37
10.[Conclusão](#conclusão)
38
38
39
-
💡 **Nota**: Ter o Entra ID como IDP não é um pré-requisito para o funcionamento com o Azure DevOps. Porém, é comum que as duas soluções sejam usadas em ambiente Microsoft.
39
+
> **Nota**: Ter o Entra ID como IDP não é um pré-requisito para o funcionamento com o Azure DevOps. Porém, é comum que as duas soluções sejam usadas em ambiente Microsoft.
40
+
{: .prompt-tip }
40
41
41
42
Para este post, criei um projeto novo no Azure DevOps chamado Backstage, que é onde armazenaremos nosso template do Backstage, nosso código Terraform e o arquivo yaml para criarmos a nossa pipeline.
42
43
43
-
⚠️ **Atenção**: Assumirei que você já sabe como criar um projeto, repositório e usar o mínimo de git necessário.
44
+
> **Atenção**: Assumirei que você já sabe como criar um projeto, repositório e usar o mínimo de git necessário.
45
+
{: .prompt-warning}
44
46
45
47
[Neste link](https://backstage.io/docs/integrations/azure/locations) você pode checar a documentação do Backstage para fazer esta integração. O Backstage suporta uso de identidade gerenciada, service principal e PAT. Para o propósito do post, vou usar PAT por ser mais simples.
46
48
@@ -238,11 +240,12 @@ spec:
238
240
entityRef: {% raw %}${{ steps.register.output.entityRef }}{% endraw %}
239
241
```
240
242
241
-
> ⚠️**Nota Importante sobre os templates**⚠️:
242
-
>
243
-
> Quando utilizamos caminho relativo na tratativa de arquivos no Backstage, ele **sempre** levará como local de partida o local de onde **o template foi importado**.
244
-
>
245
-
> Em outras palavras, ele sempre concatenará o caminho que você informar com o caminho de onde o template foi importado. Dessa forma, ou você mantém os arquivos a serem tratados no mesmo local do arquivo de onde importou o template ou utiliza uma url de um lugar externo, que foi a abordagem que usei aqui na ação `fetch:template`. Mais sobre isso pode ser visto [aqui](https://backstage.io/docs/features/software-templates/) e [aqui](https://backstage.io/docs/tooling/cli/templates/).
243
+
> **Nota Importante sobre os templates**:
244
+
245
+
Quando utilizamos caminho relativo na tratativa de arquivos no Backstage, ele **sempre** levará como local de partida o local de onde **o template foi importado**.
246
+
247
+
Em outras palavras, ele sempre concatenará o caminho que você informar com o caminho de onde o template foi importado. Dessa forma, ou você mantém os arquivos a serem tratados no mesmo local do arquivo de onde importou o template ou utiliza uma url de um lugar externo, que foi a abordagem que usei aqui na ação `fetch:template`. Mais sobre isso pode ser visto [aqui](https://backstage.io/docs/features/software-templates/) e [aqui](https://backstage.io/docs/tooling/cli/templates/).
248
+
{: .prompt-warning }
246
249
247
250
Voltando ao nosso processo, crie o arquivo do template no Azure DevOps (substituindo os campos devidos) e então vá até o Backstage e siga o mesmo processo de importação que fizemos antes no teste de integração. Na hora em que for importar o template, pode ser que se depare com o erro abaixo:
⚠️ Eu não estou usando aqui uma conta de armazenamento para que você guarde o estado do seu Terraform! Para ambientes de produção, sugiro armazenar o estado em algum lugar seguro.
281
+
> Eu não estou usando aqui uma conta de armazenamento para que você guarde o estado do seu Terraform! Para ambientes de produção, sugiro armazenar o estado em algum lugar seguro.
282
+
{: .prompt-tip }
279
283
280
284
Atenção para a variável `name`, pois ela será preenchida pelo valor que vier do Backstage. Aqui estamos fazendo um exemplo bem simples, usando somente uma variável, mas extrapole essa ideia para qualquer código que você queira executar.
281
285
282
286
Uma vez criado o código terraform, vamos fazer o upload dele para o nosso repositório do Azure DevOps.
283
287
284
-
💡 **Importante**: como a ideia é que o Backstage faça a tratativa deste arquivo e depois faça o upload e subsequente criação de um Pull Request de código, este (contendo a variável `name`) será substituído pelo valor que virá do Backstage, tornando o código **não-reutilizável**.
288
+
> **Importante**: como a ideia é que o Backstage faça a tratativa deste arquivo e depois faça o upload e subsequente criação de um Pull Request de código, este (contendo a variável `name`) será substituído pelo valor que virá do Backstage, tornando o código **não-reutilizável**.
285
289
Para evitar isso, vamos separar o código com a variável, que chamaremos de `base`, do código que terá a variável preenchida, que chamaremos de `changed`, para facilitar. Assim, sempre teremos um lugar com o código pronto para ser utilizado.
290
+
{: .prompt-info }
286
291
287
292
Abaixo segue a abordagem que entendo ser a mais simples, mas fique a vontade para adaptar à sua necessidade:
0 commit comments