<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Blog de Javier Jerónimo</title>
    <description>Blog de Ingeniería del Software, Arquitectura y Ciber Seguridad
</description>
    <link>https://javierjeronimo.es/</link>
    <atom:link href="https://javierjeronimo.es/feed.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Mon, 25 Sep 2023 14:31:56 +0000</pubDate>
    <lastBuildDate>Mon, 25 Sep 2023 14:31:56 +0000</lastBuildDate>
    <generator>Jekyll v3.9.3</generator>
    
      <item>
        <title>Mejores Prácticas con Azure Policy - SSDLC - Automatizar la revisión</title>
        <description>&lt;blockquote&gt;
  &lt;p&gt;Esta es una serie de artículos con mi experiencia después de un año en un equipo de diseño e implementación de Azure Policy en el área de Ciber Seguridad Global de Grupo Santander. En estos artículos intentaré resumir las lecciones que hemos aprendido al diseñar, implementar y mantener Azure Policy:&lt;/p&gt;

  &lt;ul&gt;
    &lt;li&gt;&lt;a href=&quot;/2020/07/18/azure-policy-design-best-practices-1/&quot;&gt;Mejores Prácticas de Diseño Azure Policy - Estructura lógica simple&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;/2020/07/20/azure-policy-design-best-practices-2/&quot;&gt;Mejores Prácticas de Diseño Azure Policy - Separación de Conceptos (SoC)&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;/2020/07/27/azure-policy-design-best-practices-3/&quot;&gt;Mejores Prácticas de Diseño Azure Policy - Control de versiones&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;/2020/08/02/azure-policy-design-best-practices-4/&quot;&gt;Mejores Prácticas de Diseño Azure Policy - Identificadores y trazabilidad&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;/2020/08/13/azure-policy-ssdlc-1/&quot;&gt;Mejores Prácticas con Azure Policy - SSDLC - Automatizar la revisión&lt;/a&gt;&lt;/li&gt;
  &lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;tabla-de-contenido&quot;&gt;Tabla de Contenido&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;#despliegue&quot;&gt;Despliegue&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#revisión-de-convenciones&quot;&gt;Revisión de convenciones&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#azure-policy---mejor-práctica-automatizar-la-revisión&quot;&gt;Azure Policy - Mejor Práctica: Automatizar la revisión&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#conclusión&quot;&gt;Conclusión&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Los artículos anteriores de esta serie de mejores prácticas introducían un conjunto de convenciones en el diseño de las definiciones de Azure Policy para que fueran facilmente gestionables. Una de mis obsesiones en proyectos software siempre ha sido que la información sea visible y accesible, pero además que se actualice de forma automática. Por eso adoro usar herramientas de gestión como Jira, donde puedes mostrar el grado de progreso de tareas, grupos de tareas (épicas) o versiones, sin más esfuero que el inicial de montar bien el proyecto. Las PPTs no se actualizan solas, supongo que por eso no me gustan tanto los informes en diapositivas.&lt;/p&gt;

&lt;p&gt;En este artículo abordo ahora otra parte importante de la gestión del proyecto de Azure Policy: el despliegue y las pruebas previas. Aquí mi obsesión es la automatización. Comencemos…&lt;/p&gt;

&lt;h2 id=&quot;despliegue&quot;&gt;Despliegue&lt;/h2&gt;

&lt;p&gt;Desde mi punto de vista el despliegue es una actividad que siendo esencial, debería ser casi transparente. Cierto es que esto requiere un nivel de madurez que permita implementarlo de forma que funcione sin problemas, pero creo que todo el tiempo que se invierta en automatizar al completo esta actividad, redunda en una mejor calidad del software que se despliega. Porque automatizar esta actividad al 100% afecta a la forma en la que se organiza el código, la configuración del propio software que se despliega, y lo hace mejorando ambos.&lt;/p&gt;

&lt;p&gt;Me gusta mucho esta recomendación [&lt;a href=&quot;https://devonblog.com/continuous-delivery/6-best-practices-for-application-deployments/&quot;&gt;ref&lt;/a&gt;]:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Deploying to production need not to be a ceremony. Production deployments need to be routine, boring events because same process is used all along for each environment. New features you deploy to production should give you excitement but not the deployment process J. You will add unnecessary complexity if you customize deployment process for each environment.&lt;/p&gt;

  &lt;p&gt;Hint: Use same repeatable and reliable way of deployments to each environments.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Y para desplegar en producción debes usar… abrimos el melón…&lt;/p&gt;

&lt;p&gt;Yo no me lío, no quiero &lt;em&gt;scripts&lt;/em&gt; complicados (despliegue &lt;em&gt;imperativo&lt;/em&gt;), me gusta la idea de definir el estado deseado y que una herramienta se encargue de hacer todo lo necesario para que se cumpla (despliegue &lt;em&gt;declarativo&lt;/em&gt;). Porque seamos realistas, conseguir &lt;em&gt;idempotencia&lt;/em&gt; con una herramienta imperativa de despliegue no es sencillo, y ya sabemos que si un despliegue falla, lo hará cuando menos tiempo tengamos para revisarlo [&lt;a href=&quot;https://es.wikipedia.org/wiki/Ley_de_Murphy&quot;&gt;ref&lt;/a&gt;]:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Todo lo que puede suceder, sucede.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;He encontrado algunas referencias en Internet sobre este asunto, y en concreto usando Terraform, que me encanta. En esta serie de artículos no voy a definir cómo implementar adecuadamente un sistema de despliegue con Terraform en varios entornos, porque hay artículos muy buenos que ya lo hacen, como este: &lt;a href=&quot;https://jloudon.com/cloud/Azure-Policy-as-Code-with-Terraform-Part-1/&quot;&gt;Azure Policy as Code with Terraform Part 1&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Siguiendo la guía del mismo autor en &lt;a href=&quot;https://jloudon.com/cloud/Using-GitHub-Actions-and-Terraform-for-IaC-Automation/&quot;&gt;Using GitHub Actions and Terraform for IaC Automation&lt;/a&gt; he creado un repositorio con un ejemplo de Azure Policy que sigue las convenciones de mi serie de artículos: &lt;a href=&quot;https://github.com/javierjeronimo/azure-policy-deploy-example&quot;&gt;https://github.com/javierjeronimo/azure-policy-deploy-example&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Una definición de Política Azure siguiendo las convenciones en el nombrado, versionado y contenido.&lt;/li&gt;
  &lt;li&gt;Un sencillo módulo Terraform para el despliegue de la misma. Ojo, que quizá existan mejores formas de desplegar cientos de definiciones y asociaciones usando &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;for_each&lt;/code&gt; y otras construcciones de Terraform.&lt;/li&gt;
  &lt;li&gt;Un pipeline de GitHub Actions donde implemento las recomendaciones de este artículo.&lt;/li&gt;
  &lt;li&gt;Una organización (gratuita) y un espacio de trabajo en &lt;a href=&quot;https://app.terraform.io/&quot;&gt;terraform.io&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;revisión-automática&quot;&gt;Revisión automática&lt;/h2&gt;

&lt;p&gt;En el proceso revisión automática, como parte de CI/CD por ejemplo, debemos automatizar la mayor cantidad posible de actividades de revisión. En nuestro caso, tenemos los siguientes puntos importantes que podríamos revisar:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;Definiciones de reglas de Azure Policy en ficheros &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.json&lt;/code&gt;.&lt;/p&gt;

    &lt;p&gt;Estos ficheros JSON deben cumplir con un esquema que define su estructura. Microsoft tiene publicado el esquema que define la forma de una definición de Azure Policy: &lt;a href=&quot;https://schema.management.azure.com/schemas/2019-09-01/policyDefinition.json&quot;&gt;https://schema.management.azure.com/schemas/2019-09-01/policyDefinition.json&lt;/a&gt;&lt;/p&gt;

    &lt;p&gt;Una comprobación que se puede automatizar facilmente consiste en comprobar si los ficheros &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.json&lt;/code&gt; cumplen con su esquema. Para ello podemos usar la herramienta &lt;a href=&quot;https://github.com/ajv-validator/ajv&quot;&gt;Ajv: Another JSON Schema Validator&lt;/a&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Módulos Terraform en ficheros &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.tf&lt;/code&gt;.&lt;/p&gt;

    &lt;p&gt;Estos ficheros se pueden comprobar con los propios comandos del CLI de Terraform: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;validate&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fmt&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;plan&lt;/code&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Convención de nombres para las definiciones de Azure Policy. Fundamental para poder automatizar la extracción de informes de trazabilidad, progreso, de nuestras definiciones.&lt;/p&gt;

    &lt;p&gt;En nuestro caso, el nombre de cada fichero JSON de Azure Policy debe seguir una convención y contener determinados campos en él. Podemos usar la herramienta &lt;a href=&quot;https://gitlab.com/winniehell/file-name-linter&quot;&gt;file-name-linter&lt;/a&gt; que mediante expresiones regulares permite añadir reglas de validación sobre ficheros.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Existen otras validaciones que se pueden hacer, que se salen del alcance de este artículo:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Comprobaciones sobre ficheros &lt;em&gt;importantes&lt;/em&gt; de un repositorio: licencia, fichero &lt;em&gt;code owners&lt;/em&gt;, plantillas de &lt;em&gt;issue&lt;/em&gt; de GitHub, etc. &lt;a href=&quot;https://github.com/todogroup/repolinter&quot;&gt;Repo Linter&lt;/a&gt;. Básicamente, que falle si alguien los borra.&lt;/li&gt;
  &lt;li&gt;Validación de documentación &lt;em&gt;Markdown&lt;/em&gt;. &lt;a href=&quot;https://github.com/igorshubovych/markdownlint-cli&quot;&gt;markdownlint-cli&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;azure-policy---mejor-práctica-automatizar-la-revisión&quot;&gt;Azure Policy - Mejor Práctica: Automatizar la revisión&lt;/h2&gt;

&lt;p&gt;Como hemos visto, hay determinadas tareas de revisión que se debe automatizar, desde las más básicas relacionadas con la sintaxis o las convenciones de formato, hasta otras como convenciones en nombres de ficheros, que pueden ser útiles como he sugerido.&lt;/p&gt;

&lt;p&gt;Por tanto, automatizar estas comprobaciones en el pipeline de CI/CD es fundamental, para que una revisión manual se pueda dedicar a aspectos más importantes, donde una persona aporta más valor que una máquina.&lt;/p&gt;

&lt;p&gt;Esta buena práctica consiste por tanto en automatizar la revisión de:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Ficheros JSON con definiciones de Azure Policy con respecto al esquema que los define.&lt;/li&gt;
  &lt;li&gt;Otros ficheros, por ejemplo, Terraform, con los correspondientes comandos del CLI.&lt;/li&gt;
  &lt;li&gt;Convenciones de nombres de ficheros, importantes para trazabilidad de Azure Policy y mejor usabilidad al revisar grado de cumplimiento.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;conclusión&quot;&gt;Conclusión&lt;/h2&gt;

&lt;p&gt;Ya programemos en un lenguaje al uso como &lt;em&gt;C&lt;/em&gt;, &lt;em&gt;JAVA&lt;/em&gt; o cualquier otra &lt;em&gt;modernez&lt;/em&gt;, o lo hagamos representando nuestra lógica de negocio en formatos como &lt;em&gt;YAML&lt;/em&gt;, &lt;em&gt;JSON&lt;/em&gt;… nuestro código fuente siempre debe cumpir con las normas de sintaxis del lenguaje en cuestión.&lt;/p&gt;

&lt;p&gt;Para lenguajes de programación de uso general, podemos revisar automáticamente la sintaxis y otros aspectos como la complejidad, la seguridad, etc., con herramientas como &lt;a href=&quot;https://github.com/SonarSource/sonarqube&quot;&gt;SonarQube&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Para herramientas que usan ficheros &lt;em&gt;XML&lt;/em&gt; o &lt;em&gt;JSON&lt;/em&gt; no disponemos de comprobaciones tan avanzadas, pero siempre tenemos la opción de revisar si los ficheros son conforme al esquema que los define. Esto es lo básico.&lt;/p&gt;

&lt;p&gt;¿Por qué? Porque no tiene sentido que una persona dedique su esfuerzo a revisar algo que puede comprobar una máquina más rápido. Tenemos que centrar nuestros esfuerzos allá donde aportamos valor, y esto está del lado de la &lt;em&gt;semántica&lt;/em&gt; de los programas (qué hacen) y no tanto del lado la &lt;em&gt;sintaxis&lt;/em&gt; (cómo están escritos). Aunque esto segundo también requiere cuidado, por aspectos como la complejidad o seguridad. Como digo, hay que dedicar los esfuerzos (y costes) de la revisión efectuada por personas allá donde aportan valor.&lt;/p&gt;

&lt;p&gt;Las definiciones de Azure Policy se implementan en ficheros en formato &lt;em&gt;JSON&lt;/em&gt; con un esquema bien definido. Esto no asegura la semántica de nuestras políticas, pero al menos sí que estas tienen la forma correcta. Y esto elimina problemas y quebraderos de cabeza futuros (post-despliegue).&lt;/p&gt;

&lt;p&gt;Además, dado que el nombre de una Azure Policy es su identificador, tanto en informes como en el portal web de Azure, como vimos en &lt;a href=&quot;/2020/08/02/azure-policy-design-best-practices-4/&quot;&gt;otro artículo&lt;/a&gt;, es fundamental definir una convención. Esto lleva a requerir automatización en la revisión de estos nombres en el proceso de CI/CD.&lt;/p&gt;

&lt;p&gt;Con estas revisiones automáticas, sabremos que no se subirán definiciones de Azure Policy incorrectas sintacticamente (lo que rompería el despliegue o la ejecución de la política), o que no tengan el nombre conforme a nuestra convención (lo que rompería nuestros informes automáticos de trazabilidad y/o progreso).&lt;/p&gt;

&lt;p&gt;En el siguiente artículo abordaré las pruebas funcionales de regresión automáticas, con las que podremos saber cómo una política se comporta con un recurso creado ad-hoc para hacerla pasar o fallar.&lt;/p&gt;
</description>
        <pubDate>Thu, 13 Aug 2020 10:00:00 +0000</pubDate>
        <link>https://javierjeronimo.es/2020/08/13/azure-policy-ssdlc-1/</link>
        <guid isPermaLink="true">https://javierjeronimo.es/2020/08/13/azure-policy-ssdlc-1/</guid>
        
        <category>azure</category>
        
        <category>policy</category>
        
        <category>shift-left</category>
        
        <category>ci/cd</category>
        
        
        <category>SecDevOps</category>
        
        <category>Cloud</category>
        
        <category>Programación</category>
        
      </item>
    
      <item>
        <title>Mejores Prácticas de Diseño Azure Policy - Identificadores y trazabilidad</title>
        <description>&lt;blockquote&gt;
  &lt;p&gt;Esta es una serie de artículos con mi experiencia después de un año en un equipo de diseño e implementación de Azure Policy en el área de Ciber Seguridad Global de Grupo Santander. En estos artículos intentaré resumir las lecciones que hemos aprendido al diseñar, implementar y mantener Azure Policy:&lt;/p&gt;

  &lt;ul&gt;
    &lt;li&gt;&lt;a href=&quot;/2020/07/18/azure-policy-design-best-practices-1/&quot;&gt;Mejores Prácticas de Diseño Azure Policy - Estructura lógica simple&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;/2020/07/20/azure-policy-design-best-practices-2/&quot;&gt;Mejores Prácticas de Diseño Azure Policy - Separación de Conceptos (SoC)&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;/2020/07/27/azure-policy-design-best-practices-3/&quot;&gt;Mejores Prácticas de Diseño Azure Policy - Control de versiones&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;/2020/08/02/azure-policy-design-best-practices-4/&quot;&gt;Mejores Prácticas de Diseño Azure Policy - Identificadores y trazabilidad&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;/2020/08/13/azure-policy-ssdlc-1/&quot;&gt;Mejores Prácticas con Azure Policy - SSDLC - Automatizar la revisión&lt;/a&gt;&lt;/li&gt;
  &lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;tabla-de-contenido&quot;&gt;Tabla de Contenido&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;#el-objetivo-de-una-azure-policy&quot;&gt;El objetivo de una Azure Policy&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#trazabilidad&quot;&gt;Trazabilidad&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#identificadores&quot;&gt;Identificadores&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#azure-policy---mejor-práctica-de-diseño-identificadores-y-trazabilidad&quot;&gt;Azure Policy - Mejor Práctica de Diseño: Versionado de definiciones e iniciativas de Azure Policy&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#conclusión&quot;&gt;Conclusión&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;En artículos anteriores vimos una serie de recomendaciones para diseñar Azure policy de forma que sean fácilmente mantenibles: diseñar todas las definiciones siguiendo una convención en su estructura lógica, que además sea simple; separando distintos conceptos en distintas definiciones y versionando las mismas individualmente y en conjunto.&lt;/p&gt;

&lt;p&gt;Siguiendo estas recomendaciones se tendrá una base de definiciones que debería crecer de forma mantenible, siendo cada una de ellas sencilla de mantener, acotada y controlada. Pero no podemos evitar la complejidad derivada del conjunto de definiciones, que crecerá irremediablemente hasta convertirse en inmanejable.&lt;/p&gt;

&lt;h2 id=&quot;el-objetivo-de-una-azure-policy&quot;&gt;El objetivo de una Azure Policy&lt;/h2&gt;

&lt;p&gt;Antes de diseñar una Azure Policy debemos tener claro el objetivo que queremos con ello. Quizá queremos detectar un recurso con atributos de seguridad inválidos (ej. no cifrado en tránsito en Storage Account) o desplegado en una región que no deseamos. Esto aplica siempre que vayamos a diseñar una nueva Azure Policy.&lt;/p&gt;

&lt;p&gt;Pero, ¿qué objetivo tenemos antes de empezar siquiera a diseñar definiciones de Azure Policy? ¿Un marco de normas de seguridad que queremos cumplir? ¿Limitar el gasto?&lt;/p&gt;

&lt;p&gt;Sea lo que sea, algún objetivo tendremos, y ese objetivo define un alcance en dos dimensiones:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;La dimensión de los productos de Azure: sobre qué productos queremos hacer las comprobaciones.&lt;/li&gt;
  &lt;li&gt;La dimensión de los atributos a revisar: qué queremos comprobar en cada producto.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Estas dos dimensiones definen la cantidad de trabajo que tenemos que hacer. Si las representamos en una tabla podemos ir rellenando las combinaciones para las que hemos creado una definición de Azure Policy:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Productos&lt;/th&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;Norma 1&lt;/th&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;Norma 2&lt;/th&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;Norma 3&lt;/th&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;…&lt;/th&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;Norma N&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Azure Key Vault&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt; &lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;X&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt; &lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt; &lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Storage Account&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;X&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;X&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;X&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt; &lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;X&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;…&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt; &lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt; &lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt; &lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt; &lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Data Factory&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt; &lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt; &lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt; &lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt; &lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;X&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Nuestro objetivo puede ser completar la tabla, o implementar Azure Policy para una columna que representa una norma crítica y prioritaria. También podría darse el caso de que el número de filas (productos Azure) fuera pequeño o creciera cada mes porque vamos usando más y más productos.&lt;/p&gt;

&lt;p&gt;En cualquier caso, esta matriz de dos dimensiones, las normas que queremos implementar y los productos de Azure, define y permite hacer un seguimiento del grado de progreso en la implementación de Azure Policy.&lt;/p&gt;

&lt;h2 id=&quot;trazabilidad&quot;&gt;Trazabilidad&lt;/h2&gt;

&lt;p&gt;Retomamos la buena práctica de la separación de conceptos y la aplicamos a la matriz de objetivo. Cada celda de la matriz representa una norma aplicada a un producto. Esto es un alcance muy bien definido y encaja a la perfección con la práctica de la separación de conceptos.&lt;/p&gt;

&lt;p&gt;Vamos a suponer un alcance muy reducido a modo de ejemplo:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Productos&lt;/th&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;Norma 1&lt;/th&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;Norma 2&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Azure Key Vault&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt; &lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Storage Account&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt; &lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt; &lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;En este ejemplo tenemos dos normas que queremos revisar y un conjunto de dos productos sobre los que hacer las comprobaciones. Por tanto, el número de definiciones de Azure Policy sería a priori de 4, cada una acotada a un producto y una norma concretos. Sencillo.&lt;/p&gt;

&lt;p&gt;Como decía en la introducción, conforme esta tabla crece en columnas o filas, el número de definiciones evidentemente también lo hace, hasta que llegue un punto donde sea complicado revisar qué tenemos y qué no. Necesitamos una forma sencilla de trazar las definiciones de Azure Policy contra nuestro objetivo (celdas de la tabla).&lt;/p&gt;

&lt;h2 id=&quot;identificadores&quot;&gt;Identificadores&lt;/h2&gt;

&lt;p&gt;Las Azure Policy se identifican por su nombre, como ya vimos en artículos anteriores. Esto hace que por ejemplo debamos incluir el número de versión como sufijo del propio nombre de la definición. Por ejemplo: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Storage_Account_Norma_1-v1.0&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Y acabo de introducir en el ejemplo lo que quería describir en este apartado…&lt;/p&gt;

&lt;p&gt;Si cada celda de la tabla corresponde con una norma y un producto Azure, si usáramos identificadores, el ejemplo anterior quedaría así:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Productos&lt;/th&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;N1&lt;/th&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;N2&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;AKV&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;N1-AKV&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;N2-AKV&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;STA&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;N1-STA&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;N2-STA&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Vamos a tomar esos identificadores como la forma de referirnos a las celdas de la tabla, que como dije, representan cada una de ellas definiciones de Azure Policy. Tendremos por tanto, cuatro potenciales definiciones de Azure Policy en este ejemplo:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;N1-AKV&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;N1-STA&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;N2-AKV&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;N2-STA&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;azure-policy---mejor-práctica-de-diseño-identificadores-y-trazabilidad&quot;&gt;Azure Policy - Mejor Práctica de Diseño: Identificadores y trazabilidad&lt;/h2&gt;

&lt;p&gt;Y con todo esto llegamos a la buena práctica de diseño de definiciones de Azure Policy: asignar identificadores a cada una, usando una convención basada en la tabla de objetivo (dimensiones de normas y productos), y usarlas en el nombre de cada definición.&lt;/p&gt;

&lt;p&gt;Es decir, siguiendo con el ejemplo anterior, y teniendo en cuenta las mejores prácticas de esta serie de artículos, tendríamos las siguientes definiciones de políticas:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;N1-AKV-v1.0.0&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;N1-STA-v1.0.0&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;N2-AKV-v1.0.0&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;N2-STA-v1.0.0&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Pueden parecer identificadores crípticos, pero hay que tener en cuenta que &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;N1&lt;/code&gt; y &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;N2&lt;/code&gt; son identificadores de nuestras propias normas. Algo más cercado a la realidad podrían ser identificadores como &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;N1&lt;/code&gt; (requisito de red 1), &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;D5&lt;/code&gt; (requisito de datos 5), &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;I2&lt;/code&gt; (requisito de IAM 2).&lt;/p&gt;

&lt;p&gt;El resultado es que tendremos una lista de ficheros con las definiciones, por ejemplo:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;policy-definitions/
    N1-AKV-v1.0.0-rule.json
    N1-STA-v1.0.0-rule.json
    N2-AKV-v1.0.0-rule.json
    N2-STA-v1.0.0-rule.json
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Con este listado de ficheros es trivial construir una hoja de cálculo donde se autorrellen las celdas de la tabla de objetivo, ya que todos los ficheros siguen la convención &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;id de norma&amp;gt;-&amp;lt;id de producto&amp;gt;-&amp;lt;version&amp;gt;-rule.json&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Ya tenemos nuestra trazabilidad y una sencilla gestión del alcance de nuestra implementación con respecto a nuestro objetivo.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Podemos rizar el rizo y añadir una tercera dimensión: el modo de la Azure Policy.&lt;/p&gt;

  &lt;p&gt;Los ficheros del ejemplo podrían quedar de la siguiente forma, donde una misma combinación norma-producto podría estar implementada en modo detectivo (&lt;em&gt;audit&lt;/em&gt;) y preventivo (&lt;em&gt;deny&lt;/em&gt;) al mismo tiempo, por ejemplo en ámbitos de asignación distintos:&lt;/p&gt;

  &lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;policy-definitions/
    N1-AKV-AUDIT-v1.0.0-rule.json
    N1-AKV-DENY-v1.0.0-rule.json
    N1-STA-AUDIT-v1.0.0-rule.json
    N2-AKV-AUDIT-v1.0.0-rule.json
    N2-STA-AUDIT-v1.0.0-rule.json
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;  &lt;/div&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;conclusión&quot;&gt;Conclusión&lt;/h2&gt;

&lt;p&gt;Separando conceptos de forma que cada definición de Azure Policy corresponda con un alcance reducido y muy determinado de nuestros objetivos conseguimos simplificar la gestión de un gran número de Azure Policy. Si añadimos a esto una convención en los nombres, permitimos automatizar la gestión de la trazabilidad.&lt;/p&gt;

&lt;p&gt;Además, esta forma de identificar y nombrar definiciones de Azure Policy nos va a obligar a seguir el principio de separación de conceptos, pues si no dicha trazabilidad automática dejará de funcionar. Estamos pues en un círculo virtuoso.&lt;/p&gt;

&lt;p&gt;El resultado es que puede crecer el número de definiciones de Azure Policy tanto como se desee, pero tendremos el control de qué tenemos y qué nos falta con respecto a nuestro objetivo. Es importante plantearse un objetivo de conjunto además del objetivo concreto de cada Azure Policy.&lt;/p&gt;

&lt;p&gt;Esto simplifica mucho la gestión del alcance. Imaginemos este entorno:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;10 controles de seguridad que queremos comprobar&lt;/li&gt;
  &lt;li&gt;40 productos de Azure, que no es nada descabellado, pongamos un ejemplo:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Generic
, ASG
, Subnet
, Routing Table
, Virtual Network
, Azure Firewall
, Load Balancer
, Network Interface
, Security Center
, DevOps
, Bastion
, Key Vault
, Private DNS
, Private Endpoint
, Recovery Vault
, Shared Image gallery
, Storage Account
, WAF
, Cognitive
, CosmosDB
, Data Bricks
, Data Factory
, Data Lake Sto g1
, HD Insights
, MSQL
, MySQL
, PostgreSQL
, Redis Cache
, Search Service
, SQL DataWarehouse
, AKS
, API Manager
, App Service
, App Serv. Env.
, Container Reg.
, EventHub
, Front Door
, Functions
, Logic App
, OpenShift cluster
, ServiceBus
, Notification HUB&lt;/p&gt;

&lt;p&gt;En este ejemplo nos salen 400 potenciales definiciones de Azure Policy. Si bien es cierto que no todas tendrán sentido, por ejemplo, porque el requisito de cifrado en tránsito no se lo apliquemos a la red virtual, o el de IAM venga implementado de forma implítica por el plan de control de Azure, este es nuestro universo de posibles Azure Policy que debemos implementar y mantener.&lt;/p&gt;

&lt;p&gt;Quiero usar ese número para demostrar que con pocos controles o normas que queramos comprobar, dado que el número de productos es grande, enseguida tendremos un número poco manejable de definciones de Azure Policy. Si no seguimos todas las buenas prácticas de diseño de esta serie de artículos, la gestión será un infierno.&lt;/p&gt;

&lt;p&gt;En siguientes artículos trataré el asunto del proceso de desarrollo: integración continua, pruebas automatizadas, etc. Vamos a apoyarnos en las prácticas de diseño y convenciones de esta serie de artículos para automatizar gran parte del trabajo de revisión que se debe hacer sobre nuevas definiciones de Azure Policy.&lt;/p&gt;
</description>
        <pubDate>Sun, 02 Aug 2020 10:00:00 +0000</pubDate>
        <link>https://javierjeronimo.es/2020/08/02/azure-policy-design-best-practices-4/</link>
        <guid isPermaLink="true">https://javierjeronimo.es/2020/08/02/azure-policy-design-best-practices-4/</guid>
        
        <category>azure</category>
        
        <category>policy</category>
        
        <category>shift-left</category>
        
        
        <category>SecDevOps</category>
        
        <category>Cloud</category>
        
        <category>Programación</category>
        
      </item>
    
      <item>
        <title>Mejores Prácticas de Diseño Azure Policy - Control de versiones</title>
        <description>&lt;blockquote&gt;
  &lt;p&gt;Esta es una serie de artículos con mi experiencia después de un año en un equipo de diseño e implementación de Azure Policy en el área de Ciber Seguridad Global de Grupo Santander. En estos artículos intentaré resumir las lecciones que hemos aprendido al diseñar, implementar y mantener Azure Policy:&lt;/p&gt;

  &lt;ul&gt;
    &lt;li&gt;&lt;a href=&quot;/2020/07/18/azure-policy-design-best-practices-1/&quot;&gt;Mejores Prácticas de Diseño Azure Policy - Estructura lógica simple&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;/2020/07/20/azure-policy-design-best-practices-2/&quot;&gt;Mejores Prácticas de Diseño Azure Policy - Separación de Conceptos (SoC)&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;/2020/07/27/azure-policy-design-best-practices-3/&quot;&gt;Mejores Prácticas de Diseño Azure Policy - Control de versiones&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;/2020/08/02/azure-policy-design-best-practices-4/&quot;&gt;Mejores Prácticas de Diseño Azure Policy - Identificadores y trazabilidad&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;/2020/08/13/azure-policy-ssdlc-1/&quot;&gt;Mejores Prácticas con Azure Policy - SSDLC - Automatizar la revisión&lt;/a&gt;&lt;/li&gt;
  &lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;tabla-de-contenido&quot;&gt;Tabla de Contenido&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;#control-de-versiones&quot;&gt;Control de versiones&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#objetivo-del-control-de-versiones&quot;&gt;Objetivo del control de versiones&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#versionado-del-conjunto-de-azure-policy&quot;&gt;Versionado del conjunto de Azure Policy&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#azure-policy---mejor-práctica-de-diseño-versionado-de-definiciones-e-iniciativas-de-azure-policy&quot;&gt;Azure Policy - Mejor Práctica de Diseño: Versionado de definiciones e iniciativas de Azure Policy&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#conclusión&quot;&gt;Conclusión&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;En el primer artículo presenté la que desde mi punto de vista es la &lt;a href=&quot;/2020/07/18/azure-policy-design-best-practices-1/&quot;&gt;primera mejor práctica al diseñar definiciones de Azure Policy&lt;/a&gt;: definir una estructura simple y crear una convención de diseño para implementar todas las definiciones. En el segundo di continuidad a ese principio con la separación de conceptos, teniendo con resultado de ambos cada política separada en su propia definición, sin mezclar conceptos y con una estructura igual en todas ellas para facilitar el mantenimiento.&lt;/p&gt;

&lt;p&gt;En este artículo vamos a gestionar la complejidad derivada de tener muchas políticas: cómo versionarlas y gestionar su despliegue en producción.&lt;/p&gt;

&lt;h2 id=&quot;control-de-versiones&quot;&gt;Control de versiones&lt;/h2&gt;

&lt;p&gt;Me gusta esta definición de la Wikipedia, es bastante sencilla [&lt;a href=&quot;https://es.wikipedia.org/wiki/Control_de_versiones&quot;&gt;referencia&lt;/a&gt;]:&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;Se llama control de versiones a la gestión de los diversos cambios que se realizan sobre los elementos de algún producto o una configuración del mismo. Una versión, revisión o edición de un producto, es el estado en el que se encuentra el mismo en un momento dado de su desarrollo o modificación.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;El control de versiones es fundamental y además es muy fácil de introducir en un proyecto: basta con alojar los ficheros en un repositorio que soporte control de versiones. En los proyectos software son habituales los sistemas de control de versiones como git. ¿Qué se consigue con ello? Pues básicamente no perder ficheros o cambios y tener un histórico de los mismos, además de que usando todas las capacidades de los sistemas de control de versiones y las formas de trabajo que permiten, se consigue que varias personas colaboren en la misma línea base de código de forma eficiente.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Primer paso: alojar los ficheros en un sistema de control de versiones. Ejemplo: git.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;objetivo-del-control-de-versiones&quot;&gt;Objetivo del control de versiones&lt;/h2&gt;

&lt;p&gt;Con los ficheros bajo control, que es lo básico, nos tenemos que plantear quién va a usar nuestras Azure Policy, porque esto define cómo debemos implementar el control de versiones.&lt;/p&gt;

&lt;p&gt;Si enfocamos cada política de forma individual, como un componente software atómico, con una finalidad bien definida (recordemos el principio de separación de conceptos que estamos aplicando), la política en sí misma podría estar versionada. Pero cuando me refiero a estar versionada no me refiero a que esté alojada y gestionada por un sistema de control de versiones, que lo está, si no que tenga versiones explícitas. Por ejemplo, una Azure Policy podría tener una versión propia v1.3.0, y si tras una serie de cambios la versión de esa política cambiara a v1.3.1, tendríamos información muy útil sobre los cambios que hubiera sufrido.&lt;/p&gt;

&lt;p&gt;En cambio, podemos ver el conjunto de todas nuestras políticas como un todo, porque por ejemplo implementen un marco de controles normativo, y necesitemos hacer referencia a qué versión de dicho marco normativo correspondan. En este caso, todas las Azure Policy estarían grupadas en un todo y este conjunto estaría versionada. Por ejemplo, podríamos tener un conjunto de Azure Policy y versionarlo como v1.1.&lt;/p&gt;

&lt;p&gt;Estos dos tipos de versionados, el individual de cada Azure Policy y el grupal de un conjunto de ellas se pueden, y deben, combinar:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;El versionado individual estaría enfocado al desarrollador de Azure Policy, o a un técnico que quiere conocer los detalles de la lógica de la política y su efecto.&lt;/p&gt;

    &lt;p&gt;Este versionado es fundamental si tratamos cada definición de Azure Policy como un componente software. Es muy fácil de implementar, puede parecer excesivo, pero a la larga mitiga el ruido y la confusión que se generan cuando hay incidencias o peticiones de soporte con respecto al efecto que están teniendo las Azure Policy que implementamos.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;El versionado en conjunto estaría enfocado al auditor, que quiere comprobar el grado de cumplimiento de sus recursos de Azure con respecto a una versión concreta del conjunto de políticas.&lt;/p&gt;

    &lt;p&gt;Sin este versionado en conjunto, un auditor no puede usar las Azure Policy como métrica de cumplimiento, pues si hacemos cambios en las políticas y el auditor no es consciente de ello, le generará incertidumbre. Con este versionado, podemos hacer cambios en definiciones individuales de políticas (por ejemplo una mejora), pero mantener el conjunto versionado sin alterar, creando una nueva versión de conjunto y dejando al auditor la elección de usar una versión de conjunto u otra para usar como métrica.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Una ventaja de usar combinar tipos de versionado es que se pueden desarrollar las Azure Policy de forma ágil, con cambios frecuentes, y controlando qué cambio sufren cada una de ellas individualmente, pero al mismo tiempo quitar incertidumbre al usuario que usa el conjunto de políticas como métrica de cumplimiento. Este segundo usuario necesita certidumbre, y esto muchas veces se traduce en cambios menos frecuentes. Por ejemplo, si un conjunto de Azure Policy se usan como métrica de seguridad del uso de Azure, quizá no se admitan cambios más que con una frecuencia anual en la definición de esas políticas.&lt;/p&gt;

&lt;h2 id=&quot;versionado-del-conjunto-de-azure-policy&quot;&gt;Versionado del conjunto de Azure Policy&lt;/h2&gt;

&lt;p&gt;Para el versioneado de un conjunto de definiciones de Azure Policy se pueden usar las &lt;em&gt;iniciativas&lt;/em&gt;, que entre sus usos también se pueden usar para asignar políticas en conjunto a un alcance determinado.&lt;/p&gt;

&lt;p&gt;Una iniciativa está relacionada con definiciones de Azure Policy, y por tanto, podemos usar la iniciativa a modo de versionado, por ejemplo &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mi-iniciativa-v1.0.0&lt;/code&gt; podría ser una iniciativa que incluya &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mi-política-1&lt;/code&gt; en su versión 1.0.0 y &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mi-política-2&lt;/code&gt; en su versión 1.0.1. Con estos dos niveles de control de versiones, podríamos mejorar &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mi-política-2&lt;/code&gt; con un cambio menor (una mejora, un añadido) y crear una nueva versión &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1.1.0&lt;/code&gt; con lo que tendríamos control de las versiones de dicha definición de Azure Policy, pero al mismo tiempo podríamos hacer que &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mi-iniciativa-v1.0.0&lt;/code&gt; no cambiara y crear una nueva &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mi-iniciativa-v1.1.0&lt;/code&gt; que incluyera la nueva versión de la política.&lt;/p&gt;

&lt;p&gt;Si no gestionamos versiones en ambos niveles, en la práctica estamos haciendo que el conjunto de definiciones de Azure Policy agrupadas en una iniciativa se convierta en un &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LATEST&lt;/code&gt;, es decir, una versión perpetua que siempre contiene lo último. Esto, como hemos dicho, genera una incertidumbre que no siempre se podrá aceptar.&lt;/p&gt;

&lt;h3 id=&quot;ventaja&quot;&gt;Ventaja&lt;/h3&gt;

&lt;p&gt;Azure Security Center permite ver en una pestaña de cumplimiento regulatorio el nivel de cumplimiento contra estándares reconocidos. Podemos hacer que una iniciativa que agrupe nuestras propias definiciones de Azure Policy sea uno de esos estándares. De esta forma, estaremos añadiendo una interfaz sencilla, centralizada en Azure Security Center, sobre el nivel de cumplimiento sobre nuestro conjunto de Azure Policy.&lt;/p&gt;

&lt;p&gt;Si decidimos darle este uso a las iniciativas, entonces necesitamos versionarlas probablemente, por aquello de dar certidumbre a quien las usa como métrica. Podríamos en ese caso publicar nuestro estándar versionado, y de hecho es lo que hace Azure:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/security_center_regulatory_compliance_versions.png&quot; alt=&quot;Azure Security Center - Regulatory Compliance&quot; title=&quot;Azure Security Center - Regulatory Compliance&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;azure-policy---mejor-práctica-de-diseño-versionado-de-definiciones-e-iniciativas-de-azure-policy&quot;&gt;Azure Policy - Mejor Práctica de Diseño: Versionado de definiciones e iniciativas de Azure Policy&lt;/h2&gt;

&lt;p&gt;Llegamos pues al resumen: es obligatorio usar control de versiones en el proceso de gestión de Azure Policy (el código), más que recomendable versionar cada definición de Azure Policy de forma individual y recomendable versionar el conjunto de Azure Policy mediante iniciativas.&lt;/p&gt;

&lt;p&gt;Y mi consejo es no reinventar la rueda y establecer un lenguaje que todos entendamos: &lt;strong&gt;semantic versioning&lt;/strong&gt;: https://semver.org/&lt;/p&gt;

&lt;p&gt;Veamos ahora cómo hacerlo…&lt;/p&gt;

&lt;h3 id=&quot;implementando-versionado-de-azure-policy&quot;&gt;Implementando versionado de Azure Policy&lt;/h3&gt;

&lt;p&gt;Básicamente tenemos dos opciones:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Añadir el número de versión como sufijo al nombre del fichero. Esto es un clásico y casi siempre es la mejor opción, porque además en este caso el nombre se usa como identificador de la Azure Policy, con lo que si queremos apuntar a distintas versiones de la misma definición va a ser la única forma de hacerlo.&lt;/p&gt;

    &lt;p&gt;De esta forma podríamos tener dos Azure Policy desplegadas:&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mi-política-1_v1.0.0&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mi-política-1_v1.1.0&lt;/code&gt;&lt;/li&gt;
    &lt;/ul&gt;

    &lt;p&gt;En realidad son la misma política, pero en distintas versiones. Si ahora tenemos una iniciativa que por ejemplo está &lt;em&gt;congelada&lt;/em&gt; porque se usa en la organización para medir el nivel de seguridad en Azure, y se ha decidido que sólo se hacen cambios en ella cada semestre previo comité, pues podemos mantener la iniciativa apuntando a la vesión 1.0.0 de la política, aunque podamos publicar una nueva versión con la corrección y darle otro uso (ej: herramienta para los equipos de desarrollo para que sepan el grado de cumplimiento que tendrán en producción recursos que están en desarrollo).&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Añadir un metadato a la definición al desplegarla en el tenant de AzureAD.&lt;/p&gt;

    &lt;p&gt;Es más limpia, pero dado que la URL que referencia a una definición de Azure Policy desplegada no incluye este campo, no servirá para referenciarla. Son simplemente metadatos muy útiles si queremos referenciar desde ellos conceptos como el commit del repo git desde el que se desplegó, la versión, etc.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
  &lt;p&gt;Posible mejora para Azure Policy: que la versión sea un atributo con entidad en las definiciones y además se pueda referenciar en la URL de forma opcional, por ejemplo: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/providers/Microsoft.Management/managementgroups/mi-management-group-1/providers/Microsoft.Authorization/policyDefinitions/mi-politica-1#v1.0.0&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;La recomendación es usar el primero, es decir, añadir un sufijo con el número de versión, tanto a los nombres de las definciones de Azure Policy como a las iniciativas que las agrupan.&lt;/p&gt;

&lt;h2 id=&quot;conclusión&quot;&gt;Conclusión&lt;/h2&gt;

&lt;p&gt;Las Azure Policy son un componente software, sí implementado en un lenguaje JSON con expresiones lógicas, pero un componente software al fin y al cabo que define el comportamiento del Azure Resource Manager, componente importante en Azure. Por tanto, usar un sistema de control de versiones (ej: git) y versionar tanto las definiciones de Azure Policy como sus agrupaciones lógicas (iniciativas) es fundamental.&lt;/p&gt;

&lt;p&gt;En el siguiente artículo trataré cómo gestionar el crecimiento descontrolado de definiciones de Azure Policy, dado que el número de productos en Azure es gigante y nuestras normas, que derivan en Azure Policy, serán complejas: cómo gestionar la trazabilidad entre las definiciones de Azure Policy que tenemos con los productos y las normas que cubren.&lt;/p&gt;
</description>
        <pubDate>Mon, 27 Jul 2020 17:00:00 +0000</pubDate>
        <link>https://javierjeronimo.es/2020/07/27/azure-policy-design-best-practices-3/</link>
        <guid isPermaLink="true">https://javierjeronimo.es/2020/07/27/azure-policy-design-best-practices-3/</guid>
        
        <category>azure</category>
        
        <category>policy</category>
        
        <category>shift-left</category>
        
        
        <category>SecDevOps</category>
        
        <category>Cloud</category>
        
        <category>Programación</category>
        
      </item>
    
      <item>
        <title>Mejores Prácticas de Diseño Azure Policy - Separación de Conceptos (SoC)</title>
        <description>&lt;blockquote&gt;
  &lt;p&gt;Esta es una serie de artículos con mi experiencia después de un año en un equipo de diseño e implementación de Azure Policy en el área de Ciber Seguridad Global de Grupo Santander. En estos artículos intentaré resumir las lecciones que hemos aprendido al diseñar, implementar y mantener Azure Policy:&lt;/p&gt;

  &lt;ul&gt;
    &lt;li&gt;&lt;a href=&quot;/2020/07/18/azure-policy-design-best-practices-1/&quot;&gt;Mejores Prácticas de Diseño Azure Policy - Estructura lógica simple&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;/2020/07/20/azure-policy-design-best-practices-2/&quot;&gt;Mejores Prácticas de Diseño Azure Policy - Separación de Conceptos (SoC)&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;/2020/07/27/azure-policy-design-best-practices-3/&quot;&gt;Mejores Prácticas de Diseño Azure Policy - Control de versiones&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;/2020/08/02/azure-policy-design-best-practices-4/&quot;&gt;Mejores Prácticas de Diseño Azure Policy - Identificadores y trazabilidad&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;/2020/08/13/azure-policy-ssdlc-1/&quot;&gt;Mejores Prácticas con Azure Policy - SSDLC - Automatizar la revisión&lt;/a&gt;&lt;/li&gt;
  &lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;tabla-de-contenido&quot;&gt;Tabla de Contenido&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;#convención-estructura-lógica-simple&quot;&gt;Convención: estructura lógica simple&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#comprobando-varios-atributos-de-un-recurso&quot;&gt;Comprobando varios atributos de un recurso&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#antes-de-seguir-operadores-prefijos--operadores-infijos-y-sintaxis-en-azure-policy&quot;&gt;Antes de seguir: operadores prefijos / operadores infijos y sintaxis en Azure Policy&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#dónde-quiero-llegar&quot;&gt;Dónde quiero llegar&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#azure-policy---mejor-práctica-de-diseño-separación-de-conceptos-soc&quot;&gt;Azure Policy - Mejor Práctica de Diseño: Separación de Conceptos (SoC)&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#conclusión&quot;&gt;Conclusión&lt;/a&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#mejora-para-sintaxis-de-azure-policy&quot;&gt;Mejora para sintaxis de Azure Policy&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;En el primer artículo presenté la que desde mi punto de vista es la &lt;a href=&quot;/2020/07/18/azure-policy-design-best-practices-1/&quot;&gt;primera mejor práctica al diseñar definiciones de Azure Policy&lt;/a&gt;: definir una estructura simple y crear una convención de diseño para implementar todas las definiciones. Vamos a retomar en el punto donde lo dejamos antes de llegar a la siguiente mejor práctica que recomiendo.&lt;/p&gt;

&lt;h2 id=&quot;convención-estructura-lógica-simple&quot;&gt;Convención: estructura lógica simple&lt;/h2&gt;

&lt;p&gt;El lenguaje usado para definir Azure Policy es un lenguaje que usa únicamente expresiones lógicas, lo que hace que la complejidad de una definición aumente descontroladamente si no se establecen unas normas básicas de diseño.&lt;/p&gt;

&lt;p&gt;Siguiendo con el razonamiento del artículo anterior, supongamos que tenemos definida la siguiente estructura como convención en el diseño de definiciones de Azure Policy:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;si( RECURSO y FILTRO y ATRIBUTO ) entonces EFECTO&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;El &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EFECTO&lt;/code&gt; en las Azure Policy está relacionado con un recurso que no es conforme a nuestra norma, es decir, cuyo atributo &lt;strong&gt;no&lt;/strong&gt; tiene el valor esperado. Vamos a actualizar la estructura para negar el atributo porque es más cercano a la realidad de las definiciones que crearemos casi siempre:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;si( RECURSO y FILTRO y (no ATRIBUTO) ) entonces EFECTO&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Por ejemplo, vamos a definir una política para comprobar que:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Todo &lt;em&gt;Storage Account&lt;/em&gt;&lt;/li&gt;
  &lt;li&gt;Con la etiqueta &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;importante&lt;/code&gt; con valor &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;si&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Deba tener protocolo HTTPS en su API activado.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;La definición, siguiendo la estructura, sería:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;si( &quot;tipo=Storage Account&quot; y &quot;etiqueta importante=si&quot; y (no &quot;https&quot;) ) entonces EFECTO&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;La estructura sigue siendo la misma, pero buscamos recursos que tengan un valor &lt;strong&gt;no esperado&lt;/strong&gt; en el atributo. Estos recursos representan un problema y sobre ellos haremos actuar a Azure:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Detectando: efecto será &lt;em&gt;audit&lt;/em&gt;.&lt;/li&gt;
  &lt;li&gt;Corrigiendo: efecto será alterar el valor para que sea el deseado.&lt;/li&gt;
  &lt;li&gt;Previniendo: efecto será &lt;em&gt;denegar&lt;/em&gt; el despliegue de todo recurso que no cumpla con la norma.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;comprobando-varios-atributos-de-un-recurso&quot;&gt;Comprobando varios atributos de un recurso&lt;/h2&gt;

&lt;p&gt;Con nuestra estructura ya adaptada al proceso de &lt;em&gt;buscar recursos no conformes con nuestra norma&lt;/em&gt; vamos a analizar qué sucede cuando necesitamos hacer más complejas las expresiones lógicas en ella.&lt;/p&gt;

&lt;p&gt;En algunos casos la expresión lógica &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RECURSO&lt;/code&gt; o &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FILTRO&lt;/code&gt; no son simples comprobaciones de un atributo. Por ejemplo, para encontrar recursos de tipo &lt;em&gt;WAF&lt;/em&gt;, debemos buscar los &lt;em&gt;Application Gateways&lt;/em&gt; de &lt;em&gt;sku=WAF&lt;/em&gt;. En este ejemplo, la condición &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RECURSO&lt;/code&gt; de nuestra estructura se convierte en una expresión lógica en sí misma:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RECURSO := tipo=&quot;Application Gateway&quot; y sku=&quot;WAF&quot;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Lo que hace que nuestra definición pase a ser:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;si( (tipo=AGW y sku=WAF) y FILTRO y (no ATRIBUTO) ) entonces EFECTO&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Vamos a complicar haciendo que el filtro nos permita encontrar los WAF que tengan la etiqueta &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sistema&lt;/code&gt; con valor &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1&lt;/code&gt; ó &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2&lt;/code&gt; (porque tenemos varios sistemas pero queremos hacer comprobaciones sólo sobre estos dos, es un ejemplo…):&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FILTRO := etiqueta sistema=1 o etiqueta sistema=2&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Completando de nuevo la definición:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;si( (tipo=AGW y sku=WAF) y (etiqueta sistema=1 o etiqueta sistema=2) y (no ATRIBUTO) ) entonces EFECTO&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Aunque en la expresión de &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RECURSO&lt;/code&gt; los parénteris no afecten al resultado (axiomas y teoremas del álgebra de Boole), los he mantenido para que se siga apreciando la convención en la estructura de la definición: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;si( RECURSO y FILTRO y (no ATRIBUTO) ) entonces EFECTO&lt;/code&gt;. Sí es importante el paréntesis en el caso de la expresión de &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FILTRO&lt;/code&gt; porque fijaos que dentro cambia el operador, que pasa a ser &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;o&lt;/code&gt; porque esperamos encontrar recursos de uno u otro tipo indistintamente, y para ambos queremos hacer la comprobación.&lt;/p&gt;

&lt;p&gt;La expresión lógica con dos condiciones &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;y&lt;/code&gt; para encontrar el tipo de recurso, y dos condiciones &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;o&lt;/code&gt; para quedarnos sólo con el subconjunto de recursos que nos interesan, ya se empieza a complicar.&lt;/p&gt;

&lt;h2 id=&quot;antes-de-seguir-operadores-prefijos--operadores-infijos-y-sintaxis-en-azure-policy&quot;&gt;Antes de seguir: operadores prefijos / operadores infijos y sintaxis en Azure Policy&lt;/h2&gt;

&lt;p&gt;Las expresiones en los lenguajes de programación se pueden escribir mediante operadores prefijos, infijos y sufijos. Por ejemplo, para la suma de &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;A&lt;/code&gt; y &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;B&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Prefijo: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;+ A B&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Infijo: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;A + B&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Sufijo: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;A B +&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;En los ejemplos que he puesto hasta ahora he usado la notación &lt;em&gt;infija&lt;/em&gt; de los operadores, porque es la que usamos de forma natural:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;si( RECURSO y FILTRO y (no ATRIBUTO) ) entonces EFECTO&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Vamos a escribir esta misma estructura con operadores prefijos:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;si( y RECURSO FILTRO (no ATRIBUTO) ) entonces EFECTO&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;O si estuviéramos en un lenguaje funcional: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;si( y( RECURSO, FILTRO, no( ATRIBUTO) ) ) ...&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Y si lo representamos en forma de árbol:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;si
    &lt;ul&gt;
      &lt;li&gt;y
        &lt;ul&gt;
          &lt;li&gt;RECURSO&lt;/li&gt;
          &lt;li&gt;FILTRO&lt;/li&gt;
          &lt;li&gt;no ATRIBUTO&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;entonces
    &lt;ul&gt;
      &lt;li&gt;EFECTO&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Y ahora el último ejemplo para tener una representación visual de una definición más compleja: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;si( (tipo=AGW y sku=WAF) y (etiqueta sistema=1 o etiqueta sistema=2) y (no ATRIBUTO) ) entonces EFECTO&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;si
    &lt;ul&gt;
      &lt;li&gt;y
        &lt;ul&gt;
          &lt;li&gt;y
            &lt;ul&gt;
              &lt;li&gt;tipo=AGW&lt;/li&gt;
              &lt;li&gt;sku=WAF&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
          &lt;li&gt;o
            &lt;ul&gt;
              &lt;li&gt;etiqueta sistema=1&lt;/li&gt;
              &lt;li&gt;etiqueta sistema=2&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
          &lt;li&gt;no
            &lt;ul&gt;
              &lt;li&gt;ATRIBUTO&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;entonces
    &lt;ul&gt;
      &lt;li&gt;EFECTO&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;En la sintaxis de Azure Policy, los operadores son prefijos:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Producto (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;y&lt;/code&gt;): se expresa con el operador prefijo &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;allOf&lt;/code&gt; (todos deben cumplirse)&lt;/li&gt;
  &lt;li&gt;Suma (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;o&lt;/code&gt;): se expresa con el operador prefijo &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;anyOf&lt;/code&gt; (alguno debe cumplirse)&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;si&lt;/code&gt;: se expresa con el operador prefijo &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;if&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;entonces&lt;/code&gt;: se expresa con el operador prefijo &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;then&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;no&lt;/code&gt;: se expresa con el operador prefijo &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;not&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Nuestro ejemplo queda como sigue:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;if
    &lt;ul&gt;
      &lt;li&gt;allOf
        &lt;ul&gt;
          &lt;li&gt;allOf
            &lt;ul&gt;
              &lt;li&gt;tipo=AGW&lt;/li&gt;
              &lt;li&gt;sku=WAF&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
          &lt;li&gt;anyOf
            &lt;ul&gt;
              &lt;li&gt;etiqueta sistema=1&lt;/li&gt;
              &lt;li&gt;etiqueta sistema=2&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
          &lt;li&gt;not
            &lt;ul&gt;
              &lt;li&gt;ATRIBUTO&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;then
    &lt;ul&gt;
      &lt;li&gt;EFECTO&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;dónde-quiero-llegar&quot;&gt;Dónde quiero llegar&lt;/h2&gt;

&lt;p&gt;Esta historia que estoy contando tiene un objetivo: demostrar que la sintaxis de las Azure Policy, al estar basada en expresiones lógicas donde combinaremos los operadores &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;y&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;o&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;no&lt;/code&gt;, condiciones sobre atributos y las propiedades distributivas y otras leyes del álgebra de Boole… llevan a que una definición de Azure Policy no &lt;em&gt;crezca&lt;/em&gt; o &lt;em&gt;envejezca&lt;/em&gt; de forma que sea facilmente mantenible.&lt;/p&gt;

&lt;p&gt;La complejidad lógica de una Azure Policy, si no se tiene como objetivo principal la simplicidad, las hace inmanejables con el paso del tiempo.&lt;/p&gt;

&lt;h2 id=&quot;azure-policy---mejor-práctica-de-diseño-separación-de-conceptos-soc&quot;&gt;Azure Policy - Mejor Práctica de Diseño: Separación de Conceptos (SoC)&lt;/h2&gt;

&lt;p&gt;Es fundamental que una definición de Azure Policy implemente un sólo concepto, una sola norma que queremos validar.&lt;/p&gt;

&lt;p&gt;Porque no es lo mismo tener una Azure Policy que tenga la estructura:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;si( RECURSO y FILTRO y (no ATRIBUTO) ) entonces EFECTO&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Que tener:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;si( RECURSO y FILTRO y (no ATRIBUTO1 o no ATRIBUTO2 o no ATRIBUTO3) ) entonces EFECTO&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Porque como hemos visto antes, ya estamos mezclando operadores anidados y en este pseudo-código se puede llegar a ver la estructura de forma sencilla, pero cuando se codifica con la sintaxis JSON de una Azure Policy, el código es más largo y menos legible.&lt;/p&gt;

&lt;p&gt;Apliquemos entonces el principio de la separación de conceptos, y del mismo modo que separamos en ficheros/métodos/clases/módulos/componentes un sistema, hagamos lo mismo con las reglas: una regla por definición.&lt;/p&gt;

&lt;p&gt;El último ejemplo quedaría:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Definición primera: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;si( RECURSO y FILTRO y (no ATRIBUTO1) ) entonces EFECTO&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Definición segunda: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;si( RECURSO y FILTRO y (no ATRIBUTO2) ) entonces EFECTO&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Definición tercera: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;si( RECURSO y FILTRO y (no ATRIBUTO3) ) entonces EFECTO&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Donde cada una de ellas es más legible, está en su propia definición, en su propio fichero JSON. Esto tiene grandes ventajas cuando varios programadores trabajan sobre la misma línea base, porque las posibilidades de conflicto en un fichero son menores, al tener más ficheros cada uno con una responsabilidad más específica.&lt;/p&gt;

&lt;h2 id=&quot;conclusión&quot;&gt;Conclusión&lt;/h2&gt;

&lt;p&gt;La segunda mejor práctica es sencilla pero algunas veces los programadores tendemos a pasarla por alto: separa conceptos. Una Azure Policy = un fichero JSON = una norma = una estructura sencilla &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;si( RECURSO y FILTRO y (no ATRIBUTO) ) entonces EFECTO&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;No pasa nada por crear más definiciones, cada una tendrá una responsabilidad bien definida, cada una será más legible.&lt;/p&gt;

&lt;h3 id=&quot;mejora-para-sintaxis-de-azure-policy&quot;&gt;Mejora para sintaxis de Azure Policy&lt;/h3&gt;

&lt;p&gt;En ingeniería del software hay una norma que consiste en no duplicar, en encapsular y reutilizar.&lt;/p&gt;

&lt;p&gt;En el ejemplo trivial donde, para un mismo tipo de recurso queríamos comprobar tres atributos distintos (tres normas distintas para el mismo tipo de atributo), teníamos:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Definición primera: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;si( RECURSO y FILTRO y (no ATRIBUTO1) ) entonces EFECTO&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Definición segunda: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;si( RECURSO y FILTRO y (no ATRIBUTO2) ) entonces EFECTO&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Definición tercera: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;si( RECURSO y FILTRO y (no ATRIBUTO3) ) entonces EFECTO&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;¿No sería bueno poder definir &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RECURSO y FILTRO&lt;/code&gt; en una &lt;em&gt;expresión&lt;/em&gt;, importarla desde nuestras definiciones y así no duplicar código?&lt;/p&gt;

&lt;p&gt;Algo como:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Definición primera: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;si( MI_PRODUCTO1 y (no ATRIBUTO1) ) entonces EFECTO&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Definición segunda: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;si( MI_PRODUCTO1 y (no ATRIBUTO2) ) entonces EFECTO&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Definición tercera: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;si( MI_PRODUCTO1 y (no ATRIBUTO3) ) entonces EFECTO&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Expresión: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MI_PRODUCTO1 := RECURSO y FILTRO&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Algo como lo siguiente, donde dos definiciones incluyen una referencia a una tercera donde se define la parte común &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RECURSO y FILTRO&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Definición primera:&lt;/p&gt;

    &lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;err&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;allOf&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;$ref&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;#/products/sta_importante&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;field&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;location&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;notEquals&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;global&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Definición segunda:&lt;/p&gt;

    &lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;err&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;allOf&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;$ref&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;#/products/sta_importante&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;field&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Microsoft.Storage/storageAccounts/supportsHttpsTrafficOnly&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;equals&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;false&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Siendo la parte común:&lt;/p&gt;

    &lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;products&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;sta_importante&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;allOf&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
          &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;field&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
          &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;equals&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Microsoft.Storage/storageAccounts&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
          &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;field&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;tags.importante&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
          &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;matchInsensitively&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;si&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Esto permitiría modularizar las expresiones lógicas y por ende, hacer más legible y mantenible el código de las Azure Policy.&lt;/p&gt;

&lt;p&gt;En el siguiente artículo continuaremos tirando del hilo sobre el hecho de que las definiciones de Azure Policy son componentes software en un sistema lo que lleva a mejores prácticas relacionadas: control de versiones, etc.&lt;/p&gt;
</description>
        <pubDate>Mon, 20 Jul 2020 22:00:00 +0000</pubDate>
        <link>https://javierjeronimo.es/2020/07/20/azure-policy-design-best-practices-2/</link>
        <guid isPermaLink="true">https://javierjeronimo.es/2020/07/20/azure-policy-design-best-practices-2/</guid>
        
        <category>azure</category>
        
        <category>policy</category>
        
        <category>shift-left</category>
        
        
        <category>SecDevOps</category>
        
        <category>Cloud</category>
        
        <category>Programación</category>
        
      </item>
    
      <item>
        <title>Mejores Prácticas de Diseño Azure Policy - Estructura lógica simple</title>
        <description>&lt;blockquote&gt;
  &lt;p&gt;Esta es una serie de artículos con mi experiencia después de un año en un equipo de diseño e implementación de Azure Policy en el área de Ciber Seguridad Global de Grupo Santander. En estos artículos intentaré resumir las lecciones que hemos aprendido al diseñar, implementar y mantener Azure Policy:&lt;/p&gt;

  &lt;ul&gt;
    &lt;li&gt;&lt;a href=&quot;/2020/07/18/azure-policy-design-best-practices-1/&quot;&gt;Mejores Prácticas de Diseño Azure Policy - Estructura lógica simple&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;/2020/07/20/azure-policy-design-best-practices-2/&quot;&gt;Mejores Prácticas de Diseño Azure Policy - Separación de Conceptos (SoC)&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;/2020/07/27/azure-policy-design-best-practices-3/&quot;&gt;Mejores Prácticas de Diseño Azure Policy - Control de versiones&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;/2020/08/02/azure-policy-design-best-practices-4/&quot;&gt;Mejores Prácticas de Diseño Azure Policy - Identificadores y trazabilidad&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;/2020/08/13/azure-policy-ssdlc-1/&quot;&gt;Mejores Prácticas con Azure Policy - SSDLC - Automatizar la revisión&lt;/a&gt;&lt;/li&gt;
  &lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;tabla-de-contenido&quot;&gt;Tabla de Contenido&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;#introducción-a-azure-policy&quot;&gt;Introducción a Azure Policy&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#álgebra-de-boole&quot;&gt;Algebra de Boole&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#azure-policy---mejor-práctica-de-diseño-simplifica-la-lógica-de-la-definición&quot;&gt;Azure Policy - Mejor Práctica de Diseño: simplifica la lógica de la definición&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#estructura-básica-de-una-azure-policy&quot;&gt;Estructura básica de una Azure Policy&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#conclusión&quot;&gt;Conclusión&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;introducción-a-azure-policy&quot;&gt;Introducción a Azure Policy&lt;/h2&gt;

&lt;p&gt;La definición más corta que se me ocurre de una Azure Policy es:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Una tecnología basada en un lenguaje JSON que permite definir reglas lógicas sobre atributos de recursos de Azure. Estas reglas lógicas (&lt;em&gt;y&lt;/em&gt;, &lt;em&gt;o&lt;/em&gt;, &lt;em&gt;entonces&lt;/em&gt;, &lt;em&gt;para todo&lt;/em&gt;, etc) ofrecen flexibilidad para implementar controles &lt;strong&gt;detectivos&lt;/strong&gt;, &lt;strong&gt;correctivos&lt;/strong&gt;, lo más importante, &lt;strong&gt;preventivos&lt;/strong&gt;, sobre recursos en Azure.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Usos que se pueden hacer de Azure Policy:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Controles detectivos&lt;/strong&gt;: lo que se suele llamar &lt;em&gt;auditoría continua&lt;/em&gt;, es decir, detección casi en tiempo real del cambio en un atributo de un recurso de nube a un valor no deseado. Por ejemplo, la desactivación de cifrado en tránsito en el API de una base de datos gestionada.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Controles correctivos&lt;/strong&gt;: como los &lt;strong&gt;detectivos&lt;/strong&gt; pero además de detectar el recurso no conforme con la regla, cambian el valor del atributo para que sea el deseado.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Controles preventivos&lt;/strong&gt;: dentro de lo que se suele llamar el &lt;em&gt;shift-left&lt;/em&gt; de la seguridad, es decir, llevar los controles de seguridad &lt;em&gt;a la izquierda&lt;/em&gt; en el ciclo de desarrollo (más cerca del diseño, mucho antes de la fase de operación y mantenimiento de los sistemas), las Azure Policy permiten implementar controles preventivos en el momento mismo de despliegue de los recursos de nube.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Haciendo uso de la propia definición de Microsoft del ciclo de desarrollo seguro del software, las Azure Policy como controles preventivos estarían en la fase &lt;em&gt;Release&lt;/em&gt;, mientras que las Azure Policy como controles detectivos y correctivos estarían en la fase &lt;em&gt;Response&lt;/em&gt;:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/microsoft-sdl-simplified.png&quot; alt=&quot;The Microsoft Security Development Lifecycle - Simplified&quot; title=&quot;The Microsoft Security Development Lifecycle - Simplified&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Es decir, con Azure Policy podemos crear por una parte reglas que detecten y corrijan recursos &lt;strong&gt;ya desplegados&lt;/strong&gt; que tienen atributos con valores no deseados, y por otra, reglas que &lt;strong&gt;impidan&lt;/strong&gt; desplegar siquiera estos recursos.&lt;/p&gt;

&lt;p&gt;Antes de continuar quiero aclarar mi postura al respecto del &lt;em&gt;shift-left&lt;/em&gt; de la seguyridad y es la siguiente: detectar y opcionalmente corregir un problema en la configuración de seguridad de un sistema cuando ya está en producción es demasiado tarde y hacerlo cuando se está en el proceso mismo de despliegue es igualmente tarde y además un generador de ruido infinito. Quien no haya sufrido las prisas de un despliegue-que-llega-tarde-para-negocio que levante la mano. Y ahora imaginad que falla porque se pasaron por alto requisitos durante la fase de diseño e implementación y la Azure Policy lo deniega. Resultado: caos absoluto.&lt;/p&gt;

&lt;h2 id=&quot;álgebra-de-boole&quot;&gt;Álgebra de Boole&lt;/h2&gt;

&lt;p&gt;Como decía en la introducción, las definiciones de &lt;em&gt;Azure Policy&lt;/em&gt; que implementan nuestros controles, lo hacen con un lenguaje basado en JSON cuya sintaxis permite definir reglas lógicas.&lt;/p&gt;

&lt;p&gt;El &lt;em&gt;álgebra de Boole&lt;/em&gt; define todas las reglas que estamos habituados a usar en programación en las expresiones condicionales, que en el álgebra de Boole reciben el nombre de operadores, axiomas, teoremas…:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;em&gt;complemento&lt;/em&gt;: que solemos llamar &lt;em&gt;negación&lt;/em&gt;, es decir, el &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NOT&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;em&gt;suma&lt;/em&gt;: que solemos llamar &lt;em&gt;o&lt;/em&gt;, es decir, el &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;OR&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;em&gt;producto&lt;/em&gt;: que solemos llamar &lt;em&gt;y&lt;/em&gt;, el &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AND&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Y todas las propiedades que más o menos aplicamos de forma automática:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;A and B&lt;/code&gt; es lo mismo que &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;B and A&lt;/code&gt; (ley conmutativa del producto).&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;A or B&lt;/code&gt; es lo mismo que &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;B or A&lt;/code&gt; (ley conmutativa de la suma).&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;not not A&lt;/code&gt; es &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;A&lt;/code&gt; (doble negación).&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;A and (B or C)&lt;/code&gt; es lo mismo que &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(A and B) or (A and C)&lt;/code&gt; (distributiva respecto del producto).&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;A or (B and C)&lt;/code&gt; es lo mismo que &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(A or B) and (A or C)&lt;/code&gt; (distributiva respecto de la suma).&lt;/li&gt;
  &lt;li&gt;…&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Y las Leyes de Morgan, que junto con lo anterior, me llevan a mi primer mejor práctica de diseño de Azure Policy:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;not (A and B)&lt;/code&gt; es lo mismo que &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(not A) or (not B)&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;not (A or B)&lt;/code&gt; es lo mismo que &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(not A) and (not B)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;azure-policy---mejor-práctica-de-diseño-simplifica-la-lógica-de-la-definición&quot;&gt;Azure Policy - Mejor Práctica de Diseño: simplifica la lógica de la definición&lt;/h2&gt;

&lt;p&gt;Antes de implementar una Azure Policy, debes dominar el álgebra de Boole. Quizá en tus estudios tuviste esta asignatura (en informática hay varias asignaturas: álgebra, lógica de primer orden, programación…), y si no, en matemáticas básicas también se tratan estos axiomas (pensando en sumas y productos en vez de en operadores &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;OR&lt;/code&gt; y &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AND&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;En cualquier caso, un programador con cierta experiencia en casi cualquier lenguaje, habrá sudado depurando condiciones lógicas en los programas que crea o mantiene.&lt;/p&gt;

&lt;p&gt;¿Por qué pongo este principio como el primero?&lt;/p&gt;

&lt;p&gt;Por lo siguiente…&lt;/p&gt;

&lt;h2 id=&quot;estructura-básica-de-una-azure-policy&quot;&gt;Estructura básica de una Azure Policy&lt;/h2&gt;

&lt;p&gt;Dejando de lado los detalles técnicos de la sintaxis de Azure Policy, que siempre tienen zonas oscuras como todo lenguaje de programación, la estructura de una Azure Policy, desde un punto de vista de alto nivel, podría ser algo así:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Tipo de recurso sobre el que quiero comprobar atributos. Por ejemplo: &lt;em&gt;Storage Account&lt;/em&gt; (&lt;em&gt;STA&lt;/em&gt;).&lt;/li&gt;
  &lt;li&gt;Filtro adicional sobre los recursos de ese tipo para aplicar el control solo a algunos. Por ejemplo, sólo las &lt;em&gt;STA&lt;/em&gt; que tengan una etiqueta concreta.&lt;/li&gt;
  &lt;li&gt;Condición sobre el atributo que quiero comprobar. Por ejemplo, si el cifrado en tránsito está desactivado (HTTPS).&lt;/li&gt;
  &lt;li&gt;Efecto: detectivo/preventivo/…&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Además, en muchos casos, la lógica de una Azure Policy es del tipo &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;si... entonces...&lt;/code&gt;, con lo que la estructura sería así:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Si…
    &lt;ol&gt;
      &lt;li&gt;El recurso es del tipo que busco, &lt;strong&gt;y&lt;/strong&gt;…&lt;/li&gt;
      &lt;li&gt;El recurso cumple con el filtro adicional, &lt;strong&gt;y&lt;/strong&gt;…&lt;/li&gt;
      &lt;li&gt;El atributo tiene el valor que busco&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
  &lt;li&gt;Entonces: el efecto debe ser…&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;De pronto, ya estamos usando álgebra de Boole:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;si ( TIPO y FILTRO y VALOR ) entonces EFECTO&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Esta estructura es sencilla de entender: si se cumplen las tres condiciones &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TIPO&lt;/code&gt; y &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FILTRO&lt;/code&gt; y el &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;VALOR&lt;/code&gt; es el esperado, entonces se produce el efecto.&lt;/p&gt;

&lt;p&gt;Sencillo, ¿no?&lt;/p&gt;

&lt;p&gt;Consejo:&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;Como en cualquier lenguaje de programación, se debe definir una convención en el diseño de Azure Policy, por ejemplo, forzando a usar siempre una misma estructura, como la definida arriba.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Consejo:&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;Y como en cualquier otro lenguaje de programación, se deben implementar comprobaciones automáticas estáticas sobre la calidad de un &lt;em&gt;programa&lt;/em&gt;: comprobar automáticamente que el fichero JSON que define una Azure Policy es conforme al esquema JSON de estas.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;conclusión&quot;&gt;Conclusión&lt;/h2&gt;

&lt;p&gt;Es muy importante partir de una estructura sencilla y establecer una convención de diseño al crear Azure Policy, porque las reglas lógicas se complican cuando hay varias condiciones, estas se anidan y aplicamos las leyes y axiomas presentados anteriormente. Disponer de una estructura para repasar a alto nivel una Azure Policy es fundamental para el proceso de revisión y la mantenibilidad de las mismas. Como en todo componente software, se implementa una vez pero se mantiene para siempre y hay que simplificar para que sea entendible.&lt;/p&gt;

&lt;p&gt;En el siguiente artículo de mejores prácticas daré continuidad a estos puntos abiertos y enlazaré con la importancia de (1) tener una estructura simple y convención de diseño de Azure Policy, y (2) conocer el álgebra de Boole al diseñar estas reglas.&lt;/p&gt;
</description>
        <pubDate>Sat, 18 Jul 2020 16:00:00 +0000</pubDate>
        <link>https://javierjeronimo.es/2020/07/18/azure-policy-design-best-practices-1/</link>
        <guid isPermaLink="true">https://javierjeronimo.es/2020/07/18/azure-policy-design-best-practices-1/</guid>
        
        <category>azure</category>
        
        <category>policy</category>
        
        <category>shift-left</category>
        
        
        <category>SecDevOps</category>
        
        <category>Cloud</category>
        
        <category>Programación</category>
        
      </item>
    
      <item>
        <title>Notes on article: Towards Secure Cloud Orchestration for Multi-Cloud Deployments</title>
        <description>&lt;h1 id=&quot;notes-on-article-towards-secure-cloud-orchestration-for-multi-cloud-deployments&quot;&gt;Notes on article: ‘Towards Secure Cloud Orchestration for Multi-Cloud Deployments’&lt;/h1&gt;

&lt;p&gt;These are just some personal notes on the article: http://doi.acm.org/10.1145/3195870.3195874&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;assumptions&quot;&gt;Assumptions&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;Hardware integrity&lt;/li&gt;
  &lt;li&gt;Physical Security&lt;/li&gt;
  &lt;li&gt;Low-Level Software Stack&lt;/li&gt;
  &lt;li&gt;Cryptographic Security&lt;/li&gt;
  &lt;li&gt;Availability&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;adversary-capabilities&quot;&gt;Adversary Capabilities&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;Network Infrastructure &amp;lt;== network is not trusted&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;high-level-attacks&quot;&gt;High Level Attacks&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;VM Substitution Attack: start vulnerable VMs&lt;/li&gt;
  &lt;li&gt;Host Substitution Attack: bypass VM placement policies.&lt;/li&gt;
  &lt;li&gt;Storage Host Substitution Attack: bypass storage placement policies.&lt;/li&gt;
  &lt;li&gt;Resource Parasite Attack: bypass infrastructure configuration policies, e.g. for running processes.&lt;/li&gt;
  &lt;li&gt;Placement Bias Attack: bypass placement policies in federated environments.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;orchestration-security-enablers&quot;&gt;Orchestration Security Enablers&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;Crypto Engine&lt;/li&gt;
  &lt;li&gt;Credential Manager&lt;/li&gt;
  &lt;li&gt;Firewall Service&lt;/li&gt;
  &lt;li&gt;PKI Manager&lt;/li&gt;
  &lt;li&gt;Attestation Service: Image Integrity Verifier, Image Delta Verifier&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sat, 05 Jan 2019 00:00:00 +0000</pubDate>
        <link>https://javierjeronimo.es/2019/01/05/notes-on-article-towards-secure-cloud/</link>
        <guid isPermaLink="true">https://javierjeronimo.es/2019/01/05/notes-on-article-towards-secure-cloud/</guid>
        
        
        <category>arquitectura</category>
        
      </item>
    
      <item>
        <title>Sistema de gestión de API &amp;#8211; KONG (2)</title>
        <description>&lt;p&gt;Hace unos años, allá por 2016, cuando trabajaba en Genexies Mobile, tuve mi primer contacto con KONG, un API manager que por aquel momento no tenía mucho recorrido (&lt;a href=&quot;/2016/03/19/sistema-de-gestion-de-api-kong/&quot;&gt;Sistema de gestión de API – KONG&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Recientemente he empezado a trabajar revisando la Arquitectura de Seguridad de un proyecto de innovación y resulta que usan KONG como API manager. Mi sorpresa ha sido mayúscula cuando he visto todo lo que había progresado el proyecto KONG desde la última vez que supe algo de él.&lt;/p&gt;

&lt;p&gt;Conforme empiece a profundizar en el análisis de la Arquitectura de Seguridad de esos componentes del sistema, iré dejando una seria de posts aquí a modo de puntos claves para hacer una integración segura de este sistema de API Manager.&lt;/p&gt;

&lt;p&gt;Saludos.&lt;/p&gt;
</description>
        <pubDate>Sat, 24 Nov 2018 00:00:00 +0000</pubDate>
        <link>https://javierjeronimo.es/2018/11/24/kong-api-manager/</link>
        <guid isPermaLink="true">https://javierjeronimo.es/2018/11/24/kong-api-manager/</guid>
        
        
        <category>arquitectura</category>
        
      </item>
    
      <item>
        <title>Instalación de minishift y Containers Development Kit (RedHat) en macOS</title>
        <description>&lt;p&gt;OpenShift es una plataforma de desarrollo basada en contenedores de RedHat, creada sobre Kubernetes y siguiendo la filosofía de muchas plataformas y frameworks actuales. Es decir, tiene un CLI para operar con ella.&lt;/p&gt;

&lt;p&gt;Minishift es un CLI para lanzar en tu propia estación de trabajo un mini-cluster de OpenShift.&lt;/p&gt;

&lt;p&gt;CDK (Containers Development Kit) son un conjunto de herramientas (JDK 1.8, entorno basado en Eclipse…) para el desarrollo rápido de aplicaciones JAVA basadas en contenedores. Básicamente, poder desarrollar aplicaciones sin tener que dedicarle mucho tiempo a montar el entorno y con un montón de configuraciones (en el IDE por ejemplo), para que desplegar en local y depurar sean acciones a las que no haya que dedicarle mucho tiempo.&lt;/p&gt;

&lt;p&gt;Son herramientas o soluciones de RedHat, pero no dejan de estar basadas en otras de código abierto, con lo que no es “peligroso” apoyarse en ellas para el desarrollo, siempre que se tenga clara la línea que separa ambas, y conociendo lo que subyace.&lt;/p&gt;

&lt;p&gt;Para instalar el entorno en macOS hay principalmente dos opciones:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Seguir las instrucciones oficiales y descargar paquetes desde el navegador.&lt;/li&gt;
  &lt;li&gt;Usar homebrew, o una mezcla de ambas, pero instalando desde esta herramienta lo más posible.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;He optado por la segunda, y aquí está la chuleta:&lt;/p&gt;

&lt;pre&gt;# Para usar virtualización &quot;nativa&quot; xhyve en macOS:
brew info --installed docker-machine-driver-xhyve

# Ahora sí:
brew install docker-machine-driver-xhyve
docker-machine-driver-xhyve need root owner and uid
sudo chown root:wheel $(brew --prefix)/opt/docker-machine-driver-xhyve/bin/docker-machine-driver-xhyve
sudo chmod u+s $(brew --prefix)/opt/docker-machine-driver-xhyve/bin/docker-machine-driver-xhyve

brew cask install minishift

# Ojito con los servicios proxy corporativos, porque la instalación captura
# la configuración y la inyecta en la máquina virtual...
export HTTPS_PROXY=&quot;http://odio.los.proxies:3128&quot;
export HTTP_PROXY=&quot;http://odio.los.proxies:3128&quot;

# Y al arrancar el cluster por primera vez, lo crea...
minishift start

# CLI de OpenShift
brew install openshift-cli

# Probando, probando, 1, 2, 3... ssssí, ssssí
eval $(minishift oc-env)
oc whoami
oc project

# Acceso via web (developer/developer por defecto en minishift):
open &quot;https://192.168.64.4:8443&quot;

# Hecho.&lt;/pre&gt;

&lt;div class=&quot;paragraph&quot;&gt;
&lt;/div&gt;

&lt;p&gt;Espero que sirva de ayuda.&lt;/p&gt;
</description>
        <pubDate>Wed, 27 Dec 2017 10:40:26 +0000</pubDate>
        <link>https://javierjeronimo.es/2017/12/27/instalacion-de-minishift-y-containers-development-kit-redhat-en-macos/</link>
        <guid isPermaLink="true">https://javierjeronimo.es/2017/12/27/instalacion-de-minishift-y-containers-development-kit-redhat-en-macos/</guid>
        
        <category>cdk</category>
        
        <category>docker</category>
        
        <category>homebrew</category>
        
        <category>kubernetes</category>
        
        <category>oc</category>
        
        <category>openshift</category>
        
        <category>redhat</category>
        
        
        <category>macos</category>
        
      </item>
    
      <item>
        <title>WineHQ en macOS: instalación de Sparx Enterprise Architect</title>
        <description>&lt;p&gt;Hace mucho tiempo que no usaba WineHQ, tenía muchas expectativas en él para la necesidad que tenía y la verdad es que no me ha decepcionado nada en absoluto.&lt;/p&gt;

&lt;p&gt;En concreto necesitaba instalar Sparx Enterprise Architect en macOS y encontré una pequeña guía en los foros de la herramienta: &lt;a href=&quot;https://www.sparxsystems.com/support/faq/enterprise-architect-WINE.html#point1&quot;&gt;https://www.sparxsystems.com/support/faq/enterprise-architect-WINE.html#point1&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Aunque las instrucciones en esa guía son para una distribución de Linux basada en Debian, sirven para macOS con algunos cambios. También tuve que hacer algunos pasos adicionales, y como en parte uso este blog como un super-post-it donde dejar anotadas cosas que quizá necesite en el futuro, pues ahí va:&lt;/p&gt;

&lt;pre&gt;brew install wine winetricks
winetricks msxml3 msxml4 mdac28

# En mi caso, por otras herramientas relacionadas con EA, tuve que instalar también:
winetricks dotnet452 corefonts

# Y para que las fuentes se vean &quot;decentes&quot;:
winetricks fontsmooth-rgb

# Finalmente:
wine msiexec /i easetupfull.msi

# Para configurar el tamaño de la fuente en pantalla:
wine winecfg&lt;/pre&gt;

&lt;p&gt;Y fin.&lt;/p&gt;
</description>
        <pubDate>Fri, 22 Dec 2017 10:36:22 +0000</pubDate>
        <link>https://javierjeronimo.es/2017/12/22/winehq-en-macos-instalacion-de-sparx-enterprise-architect/</link>
        <guid isPermaLink="true">https://javierjeronimo.es/2017/12/22/winehq-en-macos-instalacion-de-sparx-enterprise-architect/</guid>
        
        <category>EA</category>
        
        <category>os x</category>
        
        <category>wineHQ</category>
        
        
        <category>macos</category>
        
      </item>
    
      <item>
        <title>Calidad del código de proyectos de código abierto</title>
        <description>&lt;p&gt;Estamos emocionados con los proyectos de código abierto. Tanto, que en ocasiones ni miramos la licencia, pero ese es otro tema de debate…&lt;/p&gt;

&lt;p&gt;¿Has comprobado alguna vez la calidad del código de un proyecto de código abierto que usas? ¿De alguna de las decenas de dependencias que instala tu npm o maven de turno? ¿De al menos la más importante? (dejo a tu elección la definición de “importante”).&lt;/p&gt;

&lt;p&gt;Yo no.&lt;/p&gt;

&lt;p&gt;Pero…&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;Desde hace unos meses trabajo en un equipo de ciberseguridad, y entre lo que estoy aprendiendo y los boletines de seguridad a los que me estoy suscribiendo, cada vez tengo más miedito en el cuerpo.&lt;/p&gt;

&lt;p&gt;Miedito porque absolutamente todos los proyectos que conozco dependen de otros de código abierto, y porque &lt;del&gt;aporreamos el teclado&lt;/del&gt; programamos a una velocidad que nos hace pasar por alto muchas cosas, entre ellas la seguridad. No pienso siquiera en “programación segura”, es decir, que seas un verdadero Ninja de la programación (no un Ninja-postureo) y que no te hagan un overflow… o seamos más actuales, que no te hagan una inyección de SQL (es muy triste que en 2017 todavía estemos hablando de esto)… o te ejecuten código JavaScript en el servidor Node.js de tu API REST molona (porque te envíen un JSON malicioso que no sanitizas)…&lt;/p&gt;

&lt;p&gt;Y lo peor de todo es que si nos tomamos la seguridad como se merece, con un buen modelo de madurez encima de la mesa (lo hay, ya haré otro artículo al respecto), pasar de cero a “algo” es casi trivial.&lt;/p&gt;

&lt;p&gt;Repito, pasar de “no hacemos ninguna comprobación de seguridad de nuestro código” a “pasamos comprobaciones básicas en nuestro sistema de &lt;em&gt;integración casi-continua&lt;/em&gt;” es… TRI-VI-AL.&lt;/p&gt;

&lt;h1 id=&quot;mal-de-muchos-consuelo-de-tontos&quot;&gt;Mal de muchos, consuelo de tontos&lt;/h1&gt;

&lt;p&gt;Las barbaridades que se oyen sobre cómo trabajan en startups y no-tan-startups… vamos a ser positivos, vayamos a cómo hacerlo.&lt;/p&gt;

&lt;h1 id=&quot;programar-es-un-arte-y-ahora-viene-una-máquina-a-decirte-tal-o-cual&quot;&gt;Programar es un arte y ahora viene una máquina a decirte tal o cual…&lt;/h1&gt;

&lt;p&gt;Pero atención, usar analizadores estáticos de código, que es de lo que voy a hablar en el artículo, que son herramientas que buscan patrones en el código, que buscan la adhesión a convenciones… puede hacer algo de daño al principio. Siempre existen falsos positivos, hay reglas con las que no todos los ingenieros estamos de acuerdo (por eso debemos tener criterio), y algunas, aun cuando están justificadas, incluso escuecen.&lt;/p&gt;

&lt;p&gt;No puedes suponer que después de varios años escribiendo código de una forma, vayas a aceptar las recomendaciones con alegria y gozo. Algunas no te gustarán. Otras incluso harán que te aflore un sentimiento de vergüenza sobre el código que has podido escribir en el pasado. Creo que eso es positivo, significa que estás aprendiendo de los errores, pero sólo lo consigues con la mente abierta. No hay nada más objetivo que la crítica (constructiva) de un algoritmo basado en evidencias y el conocimiento de muchos ingenieros.&lt;/p&gt;

&lt;h1 id=&quot;comprobaciones-básicas-on-premise&quot;&gt;Comprobaciones básicas &lt;em&gt;on-premise&lt;/em&gt;&lt;/h1&gt;

&lt;p&gt;Voy a centrarme sólo en aplicaciones JAVA + MAVEN, pero con algo de Google se pueden encontrar alternativas para otros lenguajes para muchos de los puntos que listo a continuación (&lt;a href=&quot;https://docs.sonarqube.org/display/PLUG/Plugin+Library&quot;&gt;https://docs.sonarqube.org/display/PLUG/Plugin+Library&lt;/a&gt;).&lt;/p&gt;

&lt;h2 id=&quot;calidad-del-código-seguir-convenciones&quot;&gt;Calidad del código: seguir convenciones&lt;/h2&gt;

&lt;p&gt;A estas alturas, no vamos a discutir este tema recurrente.&lt;/p&gt;

&lt;h3 id=&quot;opción-1--cero-esfuerzo-sonarqube&quot;&gt;Opción 1 – “cero” esfuerzo (SonarQube)&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Cómo&lt;/strong&gt;: SonarQube / SonarJava, el plugin oficialmente soportado por SonarQube para JAVA hace este tipo de comprobaciones.&lt;/p&gt;

&lt;p&gt;Si usas MAVEN, instala SonarQube y después: &lt;a href=&quot;https://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner+for+Maven&quot;&gt;https://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner+for+Maven&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Qué&lt;/strong&gt;: “Coding Convention” (&lt;a href=&quot;https://www.sonarsource.com/why-us/products/codeanalyzers/sonarjava.html&quot;&gt;https://www.sonarsource.com/why-us/products/codeanalyzers/sonarjava.html&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resultado&lt;/strong&gt;: Comprobaciones típicas de JAVA.&lt;/p&gt;

&lt;h3 id=&quot;opción-2--instalar-otro-plugin-adicionalmente-sonarqube&quot;&gt;Opción 2 – Instalar otro plugin adicionalmente (SonarQube)&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Cómo&lt;/strong&gt;: SonarQube Checkstyle plugin (&lt;a href=&quot;https://github.com/checkstyle/sonar-checkstyle&quot;&gt;https://github.com/checkstyle/sonar-checkstyle&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Qué&lt;/strong&gt;: Checkstyle para JAVA (&lt;a href=&quot;http://checkstyle.sourceforge.net/&quot;&gt;http://checkstyle.sourceforge.net/&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resultado&lt;/strong&gt;: Las comprobaciones básicas de SonarJava y las de Checkstyle. Ooook.&lt;/p&gt;

&lt;h2 id=&quot;calidad-del-código-evitar-malos-olores&quot;&gt;Calidad del código: evitar malos olores&lt;/h2&gt;

&lt;p&gt;Las comunicaciones entre las personas que forman una organización imitan la estructura de la organización. Del mismo modo, el código huele según el estado de ánimo del programador en cada momento, o de sus hábitos.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cómo&lt;/strong&gt;: SonarQube / SonarJava&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Qué&lt;/strong&gt;: 218 reglas específicas de “Code Smells” (&lt;a href=&quot;https://www.sonarsource.com/why-us/products/codeanalyzers/sonarjava/rules.html#Code_Smell_Detection&quot;&gt;https://www.sonarsource.com/why-us/products/codeanalyzers/sonarjava/rules.html#Code_Smell_Detection&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resultado&lt;/strong&gt;: No sólo convenciones, si no estructuras y uso del lenguaje que tienen mala pinta… Oooooook.&lt;/p&gt;

&lt;h2 id=&quot;calidad-del-código-programación-segura-qué&quot;&gt;Calidad del código: programación segura-qué?&lt;/h2&gt;

&lt;p&gt;Hay muchas fuentes de documentación sobre seguridad (errores típicos de programación, vulnerabilidades, etc). Un &lt;a href=&quot;https://en.wikipedia.org/wiki/List_of_tools_for_static_code_analysis&quot;&gt;analizador estático de código&lt;/a&gt; es capaz de encontrar patrones de programación insegura (somos tan predecibles los programadores…), así que…&lt;/p&gt;

&lt;h3 id=&quot;opción-1--cero-esfuerzo-sonarqube-1&quot;&gt;Opción 1 – “cero” esfuerzo (SonarQube)&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Cómo&lt;/strong&gt;: SonarQube / SonarJava&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Qué&lt;/strong&gt;: 212 reglas específicas que cubren recomendaciones de seguridad de los siguientes “estándares”&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;CWE&lt;/strong&gt; (Common Weakness Enumeration): &lt;a href=&quot;https://cwe.mitre.org/&quot;&gt;https://cwe.mitre.org/&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;CWE/SANS TOP 25&lt;/strong&gt; Most Dangerous Software Errors: &lt;a href=&quot;https://www.sans.org/top25-software-errors/&quot;&gt;https://www.sans.org/top25-software-errors/&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;OWASP Top Ten&lt;/strong&gt; (10 Most Critical Web Application Security Risks): &lt;a href=&quot;https://www.owasp.org/index.php/Category:OWASP_Top_Ten_Project&quot;&gt;https://www.owasp.org/index.php/Category:OWASP_Top_Ten_Project&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;MISRA&lt;/strong&gt;: &lt;a href=&quot;https://www.misra.org.uk/MISRAHome/WhatisMISRA/tabid/66/Default.aspx&quot;&gt;https://www.misra.org.uk/MISRAHome/WhatisMISRA/tabid/66/Default.aspx&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;SEI CERT&lt;/strong&gt; (Software Engineering Institute / Carnegie Mellon University): &lt;a href=&quot;https://www.securecoding.cert.org/confluence/display&quot;&gt;https://www.securecoding.cert.org/confluence/display&lt;/a&gt;/seccode/SEI+CERT+Coding+Standards&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Resultado&lt;/strong&gt;: Resulta que sólo con SonarJava ya tenemos unas cuantas comprobaciones de calidad… Ooooooooook&lt;/p&gt;

&lt;h3 id=&quot;opción-2--owasp-dependency-check-java--net&quot;&gt;Opción 2 – OWASP Dependency Check (JAVA / .NET)&lt;/h3&gt;

&lt;p&gt;¿Usas alguna dependencia con vulnerabilidades conocidas? Lo primero es conocer la respuesta a esta pregunta, y lo segundo actualizar tus dependencias vulnerables a versiones sin esa vulnerabilidad CONOCIDA. Resalto lo de CONOCIDA.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Qué&lt;/strong&gt;: OWASP Dependency Check&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cómo&lt;/strong&gt;: herramienta integrable con MAVEN, ANT, sbt… &lt;a href=&quot;https://www.owasp.org/index.php/OWASP_Dependency_Check&quot;&gt;https://www.owasp.org/index.php/OWASP_Dependency_Check&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resultado&lt;/strong&gt;: Otro plugin más en el flujo de compilación de MAVEN, pero te obliga a mantenerte al día…&lt;/p&gt;

&lt;h2 id=&quot;comprobaciones-básicas-en-la-nube&quot;&gt;Comprobaciones básicas en-la-nube&lt;/h2&gt;

&lt;p&gt;Para proyectos de código abierto existen muchos recursos gratuitos en internet. Todas las startups están como locas captando usuarios, y las que ofrecen productos y servicios entorno al desarrollo de aplicaciones no son menos.&lt;/p&gt;

&lt;p&gt;Así que si tienes un proyecto de código abierto, te puedes evitar instalar un SonarQube, un TeamCity y toda la parafernalia que los rodea. Simplemente podrás darte de alta, indicar cuáles son tus repositorios y darle al “play”:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;SonarQube: ellos mismos ofrecen un servicio online gratuito para proyectos de código abierto, así que todas las comprobaciones de la sección anterior están disponibles.&lt;/li&gt;
  &lt;li&gt;CodeClimate: “Obtén revisiones de código automatizadas para cobertura de pruebas, complejidad, duplicación, seguridad, estilo y más, y mezcla con confianza”. Los filtros para navegar por los problemas encontrados son un poco pobres, pero es un primer paso.&lt;/li&gt;
  &lt;li&gt;Codacy: me da la impresión de que internamente usan SonarQube, la interfaz está muy cuidada y me ha gustado bastante.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Y con TravisCI completamos el ciclo…&lt;/p&gt;

&lt;h1 id=&quot;volviendo-al-tema&quot;&gt;Volviendo al tema…&lt;/h1&gt;

&lt;p&gt;Por tanto… todo software de código abierto que se precie, sin invertir un céntimo, tiene acceso a recursos que le permitirían revisar la calidad de su código, incluso desde el punto de vista de la seguridad.&lt;/p&gt;

&lt;p&gt;Supongamos que alguien, por ejemplo yo, está evaluando soluciones de código abierto de un tipo concreto. Estas ofrecen versiones “enterprise” (EE) que aportan valor adicional a la versión “community” (OSS), que será las que contrates cuando tomes la decisión de cuál usar.&lt;/p&gt;

&lt;p&gt;Al haber varias empresas ofreciendo soluciones de ese tipo, bajo ese mismo modelo de negocio OSS+EE, ¿no deberían todas ellas cuidar su código? ¿no deberían aprovechar todos los recursos que hubiera disponibles? ¿no deberían demostrar públicamente que su producto EE está sostenido por una solución de código abierto de calidad comprobable, de calidad de la buena…?&lt;/p&gt;

&lt;p&gt;Pues no. Y es una pena.&lt;/p&gt;

&lt;h1 id=&quot;solución&quot;&gt;Solución&lt;/h1&gt;

&lt;p&gt;Quieres evaluar una solución de código abierto porque te estás planteando contratar los servicios de la versión “enterprise”. Pues si ellos no han hecho bien su trabajo, al menos podrás:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Crear un “fork” de su repositorio community.&lt;/li&gt;
  &lt;li&gt;Darte tú de alta en los servicios.&lt;/li&gt;
  &lt;li&gt;Configurarlos hacia tus “forks”.&lt;/li&gt;
  &lt;li&gt;Analizar el código.&lt;/li&gt;
  &lt;li&gt;FIN.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt; &lt;/p&gt;
</description>
        <pubDate>Fri, 12 May 2017 15:33:34 +0000</pubDate>
        <link>https://javierjeronimo.es/2017/05/12/calidad-del-codigo-de-proyectos-de-codigo-abierto/</link>
        <guid isPermaLink="true">https://javierjeronimo.es/2017/05/12/calidad-del-codigo-de-proyectos-de-codigo-abierto/</guid>
        
        <category>automatización</category>
        
        <category>calidad</category>
        
        <category>integración continua</category>
        
        <category>programación</category>
        
        <category>seguridad</category>
        
        
        <category>secdevops</category>
        
      </item>
    
  </channel>
</rss>
