<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Gustavo Martin Morcuende</title>
    <description>The latest articles on DEV Community by Gustavo Martin Morcuende (@gumartinm).</description>
    <link>https://dev.to/gumartinm</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F487672%2F730e9ff4-2337-47e9-b890-f68295a04a6f.png</url>
      <title>DEV Community: Gustavo Martin Morcuende</title>
      <link>https://dev.to/gumartinm</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gumartinm"/>
    <language>en</language>
    <item>
      <title>Cómo construir tu propia data platform. From zero to hero.</title>
      <dc:creator>Gustavo Martin Morcuende</dc:creator>
      <pubDate>Fri, 09 Jun 2023 20:08:41 +0000</pubDate>
      <link>https://dev.to/adevintaspain/como-construir-tu-propia-data-platform-from-zero-to-hero-96c</link>
      <guid>https://dev.to/adevintaspain/como-construir-tu-propia-data-platform-from-zero-to-hero-96c</guid>
      <description>&lt;h2&gt;
  
  
  Introducción
&lt;/h2&gt;

&lt;p&gt;Este artículo es el resultado de la ponencia presentada el día 28 de abril de 2023 en la &lt;a href="https://salmorejo.tech/2023/"&gt;Salmorejo Tech&lt;/a&gt;. Las slides de la presentación pueden encontrarse en el siguiente enlace: &lt;a href="https://www.slideshare.net/GustavoMartin46/cmo-construir-tu-propia-data-platform-from-zero-to-hero"&gt;slideshare&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Con esta ponencia se buscaba explicar a una audiencia con conocimientos básicos de tecnología, las distintas herramientas que se pueden emplear para construir una plataforma de datos.&lt;/p&gt;

&lt;p&gt;La ponencia comienza con una configuración sencilla, que prácticamente cualquier persona del mundo de la informática puede entender. Termina con una configuración compleja, donde sin entrar en muchos detalles, sí permite a la audiencia hacerse una idea de qué herramientas se requieren para implementar la solución.&lt;/p&gt;

&lt;h2&gt;
  
  
  Diferencia entre el mundo operacional y el mundo analítico.
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TjUUEDl4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/afl0sn6atmfhcb1sz72i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TjUUEDl4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/afl0sn6atmfhcb1sz72i.png" alt="Image description" width="800" height="244"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;El mundo operacional es donde encontramos las típicas aplicaciones de frontend y backend. En este mundo no es estrictamente necesario guardar históricos de información. Aquí estamos más interesados en guardar lo que el usuario necesite para realizar sus operaciones y estas operaciones pueden caducar con el paso del tiempo. Además, en el mundo operacional, guardamos grandes cantidades de información personal como pueden ser el email, teléfonos de contacto, direcciones, etc, etc. Esto es así porque los necesitamos para contactar con el usuario. Por ejemplo, para enviarle un pedido.&lt;/p&gt;

&lt;p&gt;En el mundo analítico lo que se quiere es guardar tanta información como sea posible. En muchas ocasiones historificada. En este mundo también, no es estrictamente necesario guardar datos personales, por ejemplo el email. Aquí no necesitamos contactar con el usuario, y por tanto no necesitamos conocer su email real, pero sí que puede que estemos interesados en saber cuántos emails distintos se han utilizado en el sistema a lo largo de los años.&lt;/p&gt;

&lt;p&gt;Es en este mundo analítico donde implementaremos nuestra plataforma de datos.&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Qué es una plataforma de datos?
&lt;/h2&gt;

&lt;p&gt;Una plataforma de datos es un conjunto de aplicaciones, herramientas, bases de datos que permiten la adquisición, el almacenamiento, preparación y gobierno de datos. Es una solución completa para el procesado, ingesta, analizado y presentación de datos generados por una empresa.&lt;/p&gt;

&lt;p&gt;Ver links:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.mongodb.com/what-is-a-data-platform"&gt;https://www.mongodb.com/what-is-a-data-platform&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.splunk.com/en_us/data-insider/what-is-a-data-platform.html"&gt;https://www.splunk.com/en_us/data-insider/what-is-a-data-platform.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  ¿Quiénes son nuestros usuari@s?
&lt;/h2&gt;

&lt;p&gt;Antes de seguir adelante implementando una solución tecnológica, tenemos que identificar los usari@s que utilizarán dicha solución, así como sus necesidades de negocio.&lt;br&gt;
A continuación listamos los casos más típicos de usuarios que podemos encontrar para una plataforma de datos.&lt;/p&gt;
&lt;h3&gt;
  
  
  Data engineer.
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--X1v__0Hd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ty8cy4wmfnjvefv0c8g4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--X1v__0Hd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ty8cy4wmfnjvefv0c8g4.png" alt="Image description" width="732" height="444"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Se enfoca en el diseño, construcción, mantenimiento y gestión de infraestructuras de datos.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Implementación y gestión de sistemas de almacenamiento de datos (bases de datos, almacenamientos en la nube, etc, etc)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Asegurar que los datos estén limpios, organizados y estructurados de manera adecuada para que puedan ser utilizados de manera efectiva.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Data analysts y data scientists y machine learning engineers.
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--t0KmDpr0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p9qp474njc1xhwq5lque.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--t0KmDpr0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p9qp474njc1xhwq5lque.png" alt="Image description" width="800" height="248"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Data scientist: utiliza técnicas estadísticas y de análisis de datos para extraer información útil con el objetivo de mejorar la toma de decisiones y la eficacia de una empresa.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Data analyst: recopila, procesa y analiza datos para ayudar a las empresas a tomar decisiones informadas. Su trabajo es proporcionar información relevante y accionable para impulsar el crecimiento y el éxito empresarial.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Machine learning engineer: desarrolla y optimiza modelos de aprendizaje automático para resolver problemas empresariales complejos. Su trabajo es construir sistemas que puedan aprender y mejorar a medida que se exponen a más datos.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Solución simple.
&lt;/h2&gt;

&lt;p&gt;Ahora que ya sabemos quiénes son nuestros clientes podemos empezar a plantear soluciones. Como se anticipó en la introducción, iremos del modelo más simple al más complejo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xYPTHt4Q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xt51c5l1hnxa0cqy64t1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xYPTHt4Q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xt51c5l1hnxa0cqy64t1.png" alt="Image description" width="800" height="307"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;En esta solución, el mundo operacional y el mundo analítico comparten la misma base de datos.&lt;/p&gt;

&lt;p&gt;Observamos que todos nuestros usuarios comparten el mismo sistema. La plataforma de datos utilizará como sistema de almacenamiento la misma base de datos que el resto del sistema operacional.&lt;/p&gt;

&lt;p&gt;Para pequeñas y medianas empresas, esta puede ser una solución de compromiso, donde no se quiere añadir la complejidad que supone añadir sistemas de almacenamiento específicos para el mundo analítico.&lt;/p&gt;

&lt;p&gt;La plataforma de datos no necesitará proveer de un sistema de almacenamiento especial.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Ventajas: sistema más simple de mantener.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Inconvenientes: acciones realizadas en el mundo analítico (por ejemplo sacar datos en un dashboard) pueden afectar a operaciones como pueden ser la compra de un producto desde el frontend porque el sistema de almacenamiento es compartido.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Herramientas que tendremos que proporcionar
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wm2XszOe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mnuo5c81yk3ph59a40q4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wm2XszOe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mnuo5c81yk3ph59a40q4.png" alt="Image description" width="686" height="482"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Base de datos&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;postgresql, mysql, oracle, etc, etc&lt;/li&gt;
&lt;li&gt;esquemas&lt;/li&gt;
&lt;li&gt;tablas&lt;/li&gt;
&lt;li&gt;gestión de permisos&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Aplicaciones&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Leen tablas de la base de datos, realizan una transformación y escriben los resultados en otras tablas.
&lt;/li&gt;
&lt;li&gt;ETL, extract, transform, load&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Dashboards&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Diagramas donde se muestran datos de interés&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Machine learning&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;MLFlow&lt;/li&gt;
&lt;li&gt;Kubeflow&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Ejemplo de aplicaciones que podemos usar
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Base de datos, por ejemplo &lt;a href="https://www.postgresql.org/"&gt;PostgreSQL&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Aplicaciones como &lt;a href="https://airflow.apache.org/"&gt;Apache Airflow&lt;/a&gt; para el desarrollo de &lt;a href="https://en.wikipedia.org/wiki/Extract,_transform,_load"&gt;ETLs&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Dashboards como &lt;a href="https://www.qlik.com/"&gt;Qlik&lt;/a&gt; y &lt;a href="https://www.tableau.com/"&gt;Tableau&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Para machine learning por ejemplo podemos proporcionar &lt;a href="https://www.kubeflow.org/"&gt;Kubeflow&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Gobernanza
&lt;/h3&gt;

&lt;p&gt;Gran importancia tendrá la definición y aplicación de reglas específicas para estandarizar nombres de las tablas, bases de datos, de procesos, etc, etc.&lt;/p&gt;

&lt;p&gt;Además será importante crear reglas de utilización de las herramientas ofrecidas por la plataforma de datos. Recordemos que al final, detrás de la tecnología hay personas.&lt;/p&gt;

&lt;p&gt;Debemos evitar que se haga un mal uso de dicha tecnología, para ello la gobernanza será fundamental.&lt;/p&gt;
&lt;h2&gt;
  
  
  Solución intermedia.
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8zLvs8hE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qu7d48smwwgtnmha7abf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8zLvs8hE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qu7d48smwwgtnmha7abf.png" alt="Image description" width="800" height="304"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;En esta solución observamos que el mundo operacional ahora es mucho más complejo. &lt;/p&gt;

&lt;p&gt;Esta solución es necesaria cuando queremos evitar que procesos del mundo analítico afecten al mundo operacional. Además, el mundo operacional está compuesto por diferentes sistemas. Queremos tener todos nuestros datos analíticos en un único lugar para de este modo poder analizarlos y transformarlos de una manera sencilla.&lt;/p&gt;

&lt;p&gt;La plataforma de datos necesitará proveer en este caso de una base de datos propia y de herramientas que permitan la extracción de la información almacenada en los diferentes sistemas del mundo analítico.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ventajas: acciones realizadas en el mundo analítico no afectan al operacional porque el sistema de almacenamiento no es compartido. Todos los datos analíticos están recogidos en un único lugar.&lt;/li&gt;
&lt;li&gt;Inconvenientes: mayor complejidad y costes.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Herramientas que tendremos que proporcionar
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ift2lczN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/huxwu37vrw9fg0hr3lod.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ift2lczN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/huxwu37vrw9fg0hr3lod.png" alt="Image description" width="800" height="478"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;En esta solución las herramientas a proporcionar son las mismas que en la solución simple, pero ahora tenemos un nuevo tipo de base de datos, el Data Warehouse y aplicaciones que nos permitirán consumir información de los sistemas operacionales. El resto de las herramientas son las mismas que las que se explicaron en la anterior solución.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Data Warehouse, por ejemplo, &lt;a href="https://aws.amazon.com/redshift/"&gt;AWS Redshift&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Aplicaciones como &lt;a href="https://airflow.apache.org/"&gt;Apache Airflow&lt;/a&gt; para el desarrollo de &lt;a href="https://en.wikipedia.org/wiki/Extract,_transform,_load"&gt;ETLs&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Dashboards como &lt;a href="https://www.qlik.com/"&gt;Qlik&lt;/a&gt; y &lt;a href="https://www.tableau.com/"&gt;Tableau&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Para machine learning por ejemplo podemos proporcionar &lt;a href="https://www.kubeflow.org/"&gt;Kubeflow&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  ¿Qué es un Data Warehouse?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Es una base de datos centralizada que integra muchas fuentes de datos.&lt;/li&gt;
&lt;li&gt;Permite aislar los sistemas operacionales de los analíticos.&lt;/li&gt;
&lt;li&gt;Queries lanzadas desde el sistema analítico no afectan al operacional.&lt;/li&gt;
&lt;li&gt;Permite reorganizar la información de forma que sea más fácilmente analizable.&lt;/li&gt;
&lt;li&gt;Proporciona un único modelo de datos.&lt;/li&gt;
&lt;li&gt;Permite mantener un histórico de información que el operacional, por no necesitarla, puede borrar.&lt;/li&gt;
&lt;li&gt;Permite integrar múltiples fuentes de datos en un único lugar.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--E0n2Ta9b--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mk4w6kn4anixvq0hgurh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--E0n2Ta9b--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mk4w6kn4anixvq0hgurh.png" alt="Image description" width="702" height="604"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Modelado específico, esquema en estrella.&lt;/li&gt;
&lt;li&gt;Compuesto de tablas de hechos y de dimensiones.&lt;/li&gt;
&lt;li&gt;Tabla de hechos: sucesión de hechos, alto número de registros.&lt;/li&gt;
&lt;li&gt;Tabla de dimensiones: descripción de los hechos, pocos registros y muchos atributos.&lt;/li&gt;
&lt;li&gt;Permite la optimización de las queries en modo lectura.&lt;/li&gt;
&lt;li&gt;Permite queries más simples, sin necesidad de múltiples JOINs como podría suceder en un modelo normalizado de entidad-relación.&lt;/li&gt;
&lt;li&gt;Permisos vía GRANTs en tablas.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  ¿Qué es AWS Redshift?
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0_A3PDNN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/29ao768s1rudp7mveutw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0_A3PDNN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/29ao768s1rudp7mveutw.png" alt="Image description" width="800" height="313"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Es una solución de Data Warehouse implementada por Amazon Web Services. Sin ningún esfuerzo, en la nube, podemos crear nuestro propio servidor.&lt;/p&gt;

&lt;p&gt;En la captura de pantalla superior, se muestra la interfaz gráfica que permite crear y configurar AWS Redshift.&lt;/p&gt;

&lt;p&gt;¡&lt;strong&gt;Cuidado!&lt;/strong&gt; Nunca uses la interfaz gráfica para crear y mantener tu infraestructura en la nube. Usa siempre &lt;a href="https://en.wikipedia.org/wiki/Infrastructure_as_code"&gt;infraestructura como código&lt;/a&gt;. Con esto consigues que tu infraestructura sea reproducible, automatizable y fácilmente mantenible por cualquier persona en tu equipo u organización. Para ello hay diferentes soluciones como pueden ser &lt;a href="https://en.wikipedia.org/wiki/AWS_CloudFormation"&gt;CloudFormation&lt;/a&gt;, &lt;a href="https://en.wikipedia.org/wiki/AWS_Cloud_Development_Kit"&gt;CDK&lt;/a&gt;, &lt;a href="https://en.wikipedia.org/wiki/Terraform_(software)"&gt;Terraform&lt;/a&gt; y muchas otras.&lt;/p&gt;

&lt;p&gt;A continuación, documentamos un ejemplo de código Terraform que permite crear de forma sencilla un cluster &lt;a href="https://aws.amazon.com/redshift/redshift-serverless/"&gt;AWS Redshift serverless&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight terraform"&gt;&lt;code&gt;  &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_redshiftserverless_workgroup"&lt;/span&gt; &lt;span class="s2"&gt;"serverless"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="mi"&gt;2&lt;/span&gt;   &lt;span class="nx"&gt;workgroup_name&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;
  &lt;span class="mi"&gt;3&lt;/span&gt;   &lt;span class="nx"&gt;namespace_name&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_redshiftserverless_namespace&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;serverless&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;
  &lt;span class="mi"&gt;4&lt;/span&gt;   &lt;span class="nx"&gt;base_capacity&lt;/span&gt;        &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;base_capacity&lt;/span&gt;
  &lt;span class="mi"&gt;5&lt;/span&gt;   &lt;span class="nx"&gt;security_group_ids&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;security_group_ids&lt;/span&gt;
  &lt;span class="mi"&gt;6&lt;/span&gt;   &lt;span class="nx"&gt;subnet_ids&lt;/span&gt;           &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subnet_ids&lt;/span&gt;
  &lt;span class="mi"&gt;7&lt;/span&gt;   &lt;span class="nx"&gt;enhanced_vpc_routing&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="mi"&gt;8&lt;/span&gt;   &lt;span class="nx"&gt;publicly_accessible&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;publicly_accessible&lt;/span&gt;
  &lt;span class="mi"&gt;9&lt;/span&gt;   &lt;span class="nx"&gt;tags&lt;/span&gt;                 &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tags&lt;/span&gt;
 &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
 &lt;span class="mi"&gt;11&lt;/span&gt; 
 &lt;span class="mi"&gt;12&lt;/span&gt; &lt;span class="k"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_redshiftserverless_namespace"&lt;/span&gt; &lt;span class="s2"&gt;"serverless"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="mi"&gt;13&lt;/span&gt;   &lt;span class="nx"&gt;namespace_name&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;
 &lt;span class="mi"&gt;14&lt;/span&gt;   &lt;span class="nx"&gt;admin_username&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;admin_username&lt;/span&gt;
 &lt;span class="mi"&gt;15&lt;/span&gt;   &lt;span class="nx"&gt;admin_user_password&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;admin_user_password&lt;/span&gt;
 &lt;span class="mi"&gt;16&lt;/span&gt;   &lt;span class="nx"&gt;db_name&lt;/span&gt;              &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;db_name&lt;/span&gt;
 &lt;span class="mi"&gt;17&lt;/span&gt;   &lt;span class="nx"&gt;iam_roles&lt;/span&gt;            &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;iam_roles&lt;/span&gt;
 &lt;span class="mi"&gt;18&lt;/span&gt;   &lt;span class="nx"&gt;default_iam_role_arn&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;default_iam_role_arn&lt;/span&gt;
 &lt;span class="mi"&gt;19&lt;/span&gt;   &lt;span class="nx"&gt;tags&lt;/span&gt;                 &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tags&lt;/span&gt;
 &lt;span class="mi"&gt;20&lt;/span&gt; 
 &lt;span class="mi"&gt;21&lt;/span&gt;   &lt;span class="c1"&gt;# https://github.com/hashicorp/terraform-provider-aws/issues/26624&lt;/span&gt;
 &lt;span class="mi"&gt;22&lt;/span&gt;   &lt;span class="nx"&gt;lifecycle&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="mi"&gt;23&lt;/span&gt;     &lt;span class="nx"&gt;ignore_changes&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
 &lt;span class="mi"&gt;24&lt;/span&gt;       &lt;span class="nx"&gt;iam_roles&lt;/span&gt;
 &lt;span class="mi"&gt;25&lt;/span&gt;     &lt;span class="p"&gt;]&lt;/span&gt;
 &lt;span class="mi"&gt;26&lt;/span&gt;   &lt;span class="p"&gt;}&lt;/span&gt;
 &lt;span class="mi"&gt;27&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
 &lt;span class="mi"&gt;28&lt;/span&gt; 
 &lt;span class="mi"&gt;29&lt;/span&gt; &lt;span class="k"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_route53_record"&lt;/span&gt; &lt;span class="s2"&gt;"serverless"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="mi"&gt;30&lt;/span&gt;   &lt;span class="nx"&gt;for_each&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;toset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;route53_record_zone_ids&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="mi"&gt;31&lt;/span&gt;   &lt;span class="nx"&gt;zone_id&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;each&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;
 &lt;span class="mi"&gt;32&lt;/span&gt;   &lt;span class="nx"&gt;name&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"redshift-&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;route53_record_name&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
 &lt;span class="mi"&gt;33&lt;/span&gt;   &lt;span class="nx"&gt;type&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"CNAME"&lt;/span&gt;
 &lt;span class="mi"&gt;34&lt;/span&gt;   &lt;span class="nx"&gt;ttl&lt;/span&gt;      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;
 &lt;span class="mi"&gt;35&lt;/span&gt;   &lt;span class="nx"&gt;records&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_redshiftserverless_workgroup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;serverless&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;.*.&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;
 &lt;span class="mi"&gt;36&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Solución avanzada.
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zOJjkQdq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vglhj500ady7rn5wq5wk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zOJjkQdq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vglhj500ady7rn5wq5wk.png" alt="Image description" width="800" height="354"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;En esta solución aparecen dos nuevos elementos: el &lt;a href="https://en.wikipedia.org/wiki/Data_lake"&gt;Data Lake&lt;/a&gt; o &lt;a href="https://www.databricks.com/blog/2020/01/30/what-is-a-data-lakehouse.html"&gt;Lakehouse&lt;/a&gt;, y fuentes de datos de tipo JSON, AVRO, XML o cualquier tipo de API.&lt;/p&gt;

&lt;p&gt;Esta solución la implementaremos cuando tengamos que guardar grandes cantidades de datos no estructurados como pueden ser eventos generados por el &lt;a href="https://en.wikipedia.org/wiki/Internet_of_things"&gt;Internet de las Cosas&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ventajas: podemos guardar datos no estructurados en grandes cantidades.&lt;/li&gt;
&lt;li&gt;Inconvenientes: mayor complejidad y costes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Herramientas que tendremos que proporcionar
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wCOsel6Y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bjoz6nzjna4pu10h7ou0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wCOsel6Y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bjoz6nzjna4pu10h7ou0.png" alt="Image description" width="800" height="343"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;En esta solución las herramientas a proporcionar son las mismas que en la solución intermedia, pero ahora se añade la necesidad de implementar un Data Lake o un Lakehouse.&lt;/p&gt;

&lt;p&gt;En nuestro caso, y porque estamos usando las herramientas proporcionadas por AWS en la nube, el Lakehouse se implementará haciendo uso de &lt;a href="https://en.wikipedia.org/wiki/Amazon_S3"&gt;AWS S3&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿Qué es un Data Lake o Lakehouse?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Es un sistema de almacenamiento de datos masivo y barato.&lt;/li&gt;
&lt;li&gt;Se utiliza para almacenar grandes cantidades de información en su formato nativo, sin necesidad de que los datos estén estructurados de una manera particular (JSON, XML, logs, etc)&lt;/li&gt;
&lt;li&gt;Los datos pueden provenir de diferentes fuentes, bases de datos, sensores, registros de máquinas, APIs, etc.&lt;/li&gt;
&lt;li&gt;Permite aislar los sistemas operacionales de los analíticos.&lt;/li&gt;
&lt;li&gt;Se utilizan sistemas distribuidos como AWS S3 de Amazon o HDFS (sistema de archivos de Hadoop) &lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ¿Qué es un Data Lake o Lakehouse implementado en AWS S3?
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hL6tbVlf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/at2pyhuhwg22edqbovl6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hL6tbVlf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/at2pyhuhwg22edqbovl6.png" alt="Image description" width="800" height="249"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;En Adevinta, implementado en AWS S3 (en Amazon Cloud)&lt;/li&gt;
&lt;li&gt;Puede verse como un sistema de archivos con carpetas&lt;/li&gt;
&lt;li&gt;¡Pero no es un sistema de archivos!&lt;/li&gt;
&lt;li&gt;Los archivos se llaman objetos.&lt;/li&gt;
&lt;li&gt;Podemos usarlo mediante el Hadoop File System, Apache Spark, etc, etc.&lt;/li&gt;
&lt;li&gt;Permisos vía IAM Roles.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ¿Cómo podemos usar el Data Lake o Lakehouse?
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Xg6o8GNj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o4yjvscm8mumt2j5atpc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Xg6o8GNj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o4yjvscm8mumt2j5atpc.png" alt="Image description" width="800" height="287"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para poder usarlo existen aplicaciones como Apache Spark. En la captura de pantalla superior, se muestra un notebook ejecutando código Apache Spark que permite leer un archivo comprimido en formato gzip y mostrar la información que contiene.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusión.
&lt;/h2&gt;

&lt;p&gt;En esta ponencia hemos presentado diferentes soluciones para construir una plataforma de datos. Desde la más sencilla hasta la más compleja. Otras soluciones son posibles, pero todas ellas tendrán piezas muy similares a las aquí discutidas.&lt;/p&gt;

&lt;p&gt;Ahora ya solo queda que tú también montes en tu empresa tu propia data platform y logres ese ascenso o mejora laboral que te mereces.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How to build your own data platform. Episode 2: authorization layer. Data Warehouse implementation.</title>
      <dc:creator>Gustavo Martin Morcuende</dc:creator>
      <pubDate>Sun, 04 Jun 2023 23:05:20 +0000</pubDate>
      <link>https://dev.to/adevintaspain/how-to-build-your-own-data-platform-episode-2-authorization-layer-data-warehouse-implementation-e0c</link>
      <guid>https://dev.to/adevintaspain/how-to-build-your-own-data-platform-episode-2-authorization-layer-data-warehouse-implementation-e0c</guid>
      <description>&lt;h2&gt;
  
  
  Introduction.
&lt;/h2&gt;

&lt;p&gt;This article is the second part of the episode about building an authorization layer for your data platform. You can find the whole list of articles following this link: &lt;a href="https://medium.com/@gu.martinm/list/how-to-build-your-own-data-platform-9e6f85e4ce39"&gt;https://medium.com/@gu.martinm/list/how-to-build-your-own-data-platform-9e6f85e4ce39&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the previous article we talked about how to implement the authorization layer in the Data Lake, in this second part we will be talking about the same but in the Data Warehouse.&lt;/p&gt;




&lt;h2&gt;
  
  
  Authorization layer.
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JDH8DWLr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eeokawvxsm6zmz1dkg39.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JDH8DWLr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eeokawvxsm6zmz1dkg39.png" alt="Image description" width="800" height="335"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can see in this diagram the Lakehouse with its metastore and the Data Warehouse. We already talked about the authorization layer for the Lakehouse in the previous article. Now it is the turn for the Data Warehouse.&lt;/p&gt;

&lt;p&gt;Because we will be using &lt;a href="https://en.wikipedia.org/wiki/Amazon_Web_Services"&gt;Amazon Web Services&lt;/a&gt; with &lt;a href="https://aws.amazon.com/redshift/"&gt;AWS Redshift&lt;/a&gt;, we will be implementing this layer using &lt;a href="https://aws.amazon.com/lake-formation/"&gt;Lake Formation&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Processing layer.
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xyYf0tRZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ccdijsa6snug3hpkh95o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xyYf0tRZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ccdijsa6snug3hpkh95o.png" alt="Image description" width="800" height="528"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Human users and processes will be the ones accessing the stored data through the authorization layer. Machines and processes like Zeppelin notebooks, AWS Athena for SQL, clusters of AWS EMR, Databricks, etc, etc.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem with the authorization.
&lt;/h2&gt;

&lt;p&gt;Data engineers, data analysts and data scientists work in different and sometimes isolated teams. They do not want their data to be deleted or changed by tools or people outside their teams.&lt;/p&gt;

&lt;p&gt;Data owners are typically in charge of granting access to their data.&lt;/p&gt;

&lt;h3&gt;
  
  
  Owner — consumer, relationship.
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fleeuAEl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/75l47konu6302lr6756y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fleeuAEl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/75l47konu6302lr6756y.png" alt="Image description" width="766" height="822"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;A data consumer requests access to some data owned by a different team in a different domain. For example, a table in a database.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The data owner grants access by approving the access request.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Upon the approval of an access request, a new permission is added to the specific table.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Our authorization layer must be able to provide the above capability if we want to implement a data mesh with success.&lt;/p&gt;

&lt;h2&gt;
  
  
  Data Warehouse, AWS Redshift.
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--B2yaFplg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w9wi6bmx0jjjxlcmvhm2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--B2yaFplg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w9wi6bmx0jjjxlcmvhm2.png" alt="Image description" width="800" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Data Warehouse is implemented on the top of AWS Redshift. Not many years ago a new service was released by Amazon called AWS Redshift RA3. What makes RA3 different from the old Redshift is that, in the new implementation, computation and storage are separated. Before having RA3, if users needed more storage capabilities, more computation had also to be paid even if computation was not a problem. And in the opposite way, when users needed more computation capabilities, more storage had to be paid. So, Redshift costs were typically high.&lt;/p&gt;

&lt;p&gt;We will be using AWS Redshift RA3. Here you can find some useful links that explain further what are AWS Redshift and AWS Redshift RA3:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/redshift/latest/mgmt/welcome.html"&gt;https://docs.aws.amazon.com/redshift/latest/mgmt/welcome.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/blogs/big-data/use-amazon-redshift-ra3-with-managed-storage-in-your-modern-data-architecture/"&gt;https://aws.amazon.com/blogs/big-data/use-amazon-redshift-ra3-with-managed-storage-in-your-modern-data-architecture/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Data Warehouse, AWS Redshift RA3.
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kLYViEDG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3u3w0ahowrt0kummulkf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kLYViEDG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3u3w0ahowrt0kummulkf.png" alt="Image description" width="800" height="307"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Amazon Redshift data sharing allows you to securely and easily share data for read purposes across different Amazon Redshift clusters without the complexity and delays associated with data copies and data movement. Data can be shared at many levels, including schemas, tables, views, and user-defined functions, providing fine-grained access controls that can be tailored for different users and businesses that all need access to the data.&lt;/p&gt;

&lt;p&gt;Lake Formation can be integrated with data sharing.&lt;/p&gt;

&lt;p&gt;For further information visit the following links:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/blogs/big-data/announcing-amazon-redshift-data-sharing-preview/"&gt;https://aws.amazon.com/blogs/big-data/announcing-amazon-redshift-data-sharing-preview/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/blogs/big-data/centrally-manage-access-and-permissions-for-amazon-redshift-data-sharing-with-aws-lake-formation/"&gt;https://aws.amazon.com/blogs/big-data/centrally-manage-access-and-permissions-for-amazon-redshift-data-sharing-with-aws-lake-formation/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Authorization, Federated Lake Formation.
&lt;/h2&gt;

&lt;p&gt;Using Lake Formation with AWS Redshift RA3 we can manage the permissions across different accounts from only one central account in a federated way. We are delegating permissions to other accounts but we keep the control of them.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HT7y-pkT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/chs87i0uufo1gcb9a72w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HT7y-pkT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/chs87i0uufo1gcb9a72w.png" alt="Image description" width="800" height="278"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Authorization, implementation.
&lt;/h2&gt;

&lt;p&gt;In order to implement federated authorization with AWS Redshift RA3 you can follow the next steps:&lt;/p&gt;

&lt;p&gt;AWS Redshift RA3, producer account:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CREATE DATASHARE producer_sharing&lt;/li&gt;
&lt;li&gt;GRANT USAGE ON DATASHARE producer_sharing TO ACCOUNT ‘FEDERATED_GOVERNANCE’&lt;/li&gt;
&lt;li&gt;ALTER DATASHARE producer_sharing ADD SCHEMA producer_schema&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AWS Redshift RA3, consumer account:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CREATE DATASHARE consumer_sharing&lt;/li&gt;
&lt;li&gt;GRANT USAGE ON DATASHARE consumer_sharing TO ACCOUNT ‘FEDERATED_GOVERNANCE’&lt;/li&gt;
&lt;li&gt;ALTER DATASHARE consumer_sharing ADD SCHEMA consumer_schema&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AWS Redshift RA3, main federated account:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Through Lake formation console, allow access from consumer account to producer_sharing. You can see a screenshot about this configuration down below.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aLzrxyZu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ix5ykv1gb09i9zjc8rln.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aLzrxyZu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ix5ykv1gb09i9zjc8rln.png" alt="Image description" width="800" height="453"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With the above configuration, the query from the consumer account will only see the column &lt;code&gt;brand_id&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PLoYeKa9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6k87khycwuml8l7fo4qo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PLoYeKa9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6k87khycwuml8l7fo4qo.png" alt="Image description" width="800" height="409"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion.
&lt;/h2&gt;

&lt;p&gt;In this article we have explained how you can implement an authorization layer using AWS AWS Redshift RA3 and AWS Lake Formation.&lt;/p&gt;

&lt;p&gt;With this authorization layer we will be able to resolve the following problems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Producers and consumers from different domains must have the capability of working in an isolated way (if they wish so) if we want to implement a data mesh with success.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Producers must be able to decide how consumers can access their data. They are the data owners, and they decide how others use their data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fine grained permissions can be established. At column and even if we want, at row level. This will be of great interest if we want to be GDPR compliant. More information about how to implement the GDPR in your own data platform will be explained in future articles.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Stay tuned for the next article about how to implement your own Data Platform with success.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I hope this article was useful. If you enjoy messing around with Big Data, Microservices, reverse engineering or any other computer stuff and want to share your experiences with me, just follow &lt;a href="https://twitter.com/gumartinm"&gt;me&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>datamesh</category>
      <category>dataplatform</category>
      <category>redshift</category>
      <category>lakeformation</category>
    </item>
    <item>
      <title>How to build your own data platform. Episode 2: authorization layer. Data Lake implementation.</title>
      <dc:creator>Gustavo Martin Morcuende</dc:creator>
      <pubDate>Fri, 02 Jun 2023 21:43:39 +0000</pubDate>
      <link>https://dev.to/adevintaspain/how-to-build-your-own-data-platform-episode-2-authorization-layer-data-lake-implementation-22l9</link>
      <guid>https://dev.to/adevintaspain/how-to-build-your-own-data-platform-episode-2-authorization-layer-data-lake-implementation-22l9</guid>
      <description>&lt;h2&gt;
  
  
  Introduction.
&lt;/h2&gt;

&lt;p&gt;This is the second episode in the series about how to build your own data platform. You can find the whole list of articles in the following link &lt;a href="https://medium.com/@gu.martinm/list/how-to-build-your-own-data-platform-9e6f85e4ce39"&gt;https://medium.com/@gu.martinm/list/how-to-build-your-own-data-platform-9e6f85e4ce39&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Remember, a data platform will be used by many teams and users. Also the data to be stored could be coming from many and different sources. Data owners will want to set permissions and boundaries about who can access the data that they are storing in the data platform. &lt;/p&gt;

&lt;p&gt;In this episode I will explain how you can add these capabilities to your data platform. Also I will introduce the concept of &lt;a href="https://en.wikipedia.org/wiki/Data_mesh"&gt;data mesh&lt;/a&gt;, and how you can use the authorization layer for implementing the workflow between data consumers and data owners that you will need for creating a successful data mesh.&lt;/p&gt;




&lt;h2&gt;
  
  
  Authorization layer.
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--N45XVE7B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zvqr33kdqbct0r48nn7w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--N45XVE7B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zvqr33kdqbct0r48nn7w.png" alt="Image description" width="800" height="326"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our authorization layer will be on the top of the storage one. In this way, users and applications willing to use the stored data will need to do it through this layer in a safe way. No data will escape from the storage layer without authorization.&lt;br&gt;
For implementing this layer you can use different solutions like &lt;a href="https://www.databricks.com/product/unity-catalog"&gt;Unity Catalog&lt;/a&gt; from Databricks, &lt;a href="https://aws.amazon.com/lake-formation/"&gt;Lake Formation&lt;/a&gt; from AWS, plain &lt;a href="https://docs.aws.amazon.com/IAM/latest/UserGuide/introduction.html"&gt;IAM&lt;/a&gt; roles also from AWS, &lt;a href="https://ranger.apache.org/"&gt;Apache Ranger&lt;/a&gt;, &lt;a href="https://privacera.com/"&gt;Privacera&lt;/a&gt; and many others.&lt;/p&gt;

&lt;p&gt;For this article, and because we are working with Amazon Web Services, we will be implementing this layer using IAM roles and Lake Formation.&lt;/p&gt;
&lt;h2&gt;
  
  
  Processing layer.
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MYKzhibH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e8792221phjqc31znbm1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MYKzhibH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e8792221phjqc31znbm1.png" alt="Image description" width="800" height="521"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Human users and processes will be the ones accessing the stored data through the authorization layer. Machines and processes like&lt;a href="https://docs.aws.amazon.com/es_es/emr/latest/ReleaseGuide/emr-zeppelin.html"&gt; Zeppelin notebooks&lt;/a&gt;, &lt;a href="https://aws.amazon.com/athena/"&gt;AWS Athena&lt;/a&gt; for SQL, clusters of &lt;a href="https://aws.amazon.com/emr/"&gt;AWS EMR&lt;/a&gt;, &lt;a href="https://www.databricks.com/"&gt;Databricks&lt;/a&gt;, etc, etc.&lt;/p&gt;
&lt;h2&gt;
  
  
  The problem with the authorization.
&lt;/h2&gt;

&lt;p&gt;Data engineers, data analysts and data scientists work in different and sometimes isolated teams. They do not want their data to be deleted or changed by tools or people outside their teams. &lt;/p&gt;

&lt;p&gt;Also, for being &lt;a href="https://en.wikipedia.org/wiki/General_Data_Protection_Regulation"&gt;GDPR&lt;/a&gt; compliant, to access &lt;a href="https://en.wikipedia.org/wiki/Personal_data"&gt;PII&lt;/a&gt; data, big restrictions will be required even at column or row level. &lt;/p&gt;

&lt;p&gt;Every stored data needs to have an owner, and in Data Mesh, data owners are typically in charge of granting access to their data.&lt;/p&gt;
&lt;h2&gt;
  
  
  What is a Data mesh?
&lt;/h2&gt;

&lt;p&gt;Taken from &lt;a href="https://www.datamesh-architecture.com/#what-is-data-mesh"&gt;https://www.datamesh-architecture.com/#what-is-data-mesh&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zLMEBH_J--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8bgtdcweu403xixt0gy5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zLMEBH_J--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8bgtdcweu403xixt0gy5.png" alt="Image description" width="800" height="511"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The term data mesh, coined in 2019 by &lt;a href="https://martinfowler.com/articles/data-mesh-principles.html"&gt;Zhamak Dehghani&lt;/a&gt;, is based on four key principles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Domain ownership: Domain teams are responsible for their data, aligning with the boundaries of their team's domain. &lt;strong&gt;An authorization layer will be required for implementing those boundaries for some team&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Data as a product: Analytical data should be treated as a product, with consumers beyond the domain. &lt;strong&gt;An owner-consumer relationship will exist, where consumers require access to products owned by a different team.&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Self-serve data infrastructure platform: A data platform team provides domain-agnostic tools and systems to build, execute, and maintain data products.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Federated governance: Interoperability of data products is achieved through standardization promoted by the governance group.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Owner - consumer, relationship.
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gXDwwtL---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lpj6odko10ldaotgctge.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gXDwwtL---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lpj6odko10ldaotgctge.png" alt="Image description" width="756" height="822"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A data consumer requests access to some data owned by a different team in a different domain. For example, a table in a database.&lt;/li&gt;
&lt;li&gt;The data owner grants access by approving the access request.&lt;/li&gt;
&lt;li&gt;Upon the approval of an access request, a new permission is added to the specific table.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Our authorization layer must be able to provide the above capability if we want to implement a data mesh with success.&lt;/p&gt;
&lt;h2&gt;
  
  
  Data Lake.
&lt;/h2&gt;

&lt;p&gt;In this section we will write a brief recap about what we explained in previous article: &lt;a href="https://medium.com/@gu.martinm/how-to-build-your-own-data-platform-f273014701ff"&gt;https://medium.com/@gu.martinm/how-to-build-your-own-data-platform-f273014701ff&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  AWS S3.
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ihIahoPU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dfcoir117w9w1q6ukqj5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ihIahoPU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dfcoir117w9w1q6ukqj5.png" alt="Image description" width="800" height="344"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Notebooks, Spark jobs, clusters, etc, etc, run in Amazon virtual servers called EC2.&lt;br&gt;
These virtual servers require permissions for accessing AWS S3. These permissions are given by IAM Roles.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We will be working with Amazon Web Services. As we said before, because the amount of data to be stored is huge, we can not use HDD or SSD data storages, we need something cheaper. In this case we will be talking about AWS S3.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Also, in order to ease the use of the Data Lake, we can implement metastores on the top of it. For example, Hive Metastore or Glue Catalog. We are not going to explain deeply how a metastore works, that will be left for another future article.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When using a notebook (for example a Databricks notebook) and having a metastore, the first thing that the notebook will do is to ask the metastore where the data is physically located. Once the metastore responds, the notebook will go to the path in AWS S3 where the data is stored using the permissions given by the IAM Role.&lt;/p&gt;
&lt;h3&gt;
  
  
  Direct access or with a metastore.
&lt;/h3&gt;

&lt;p&gt;We have two options for working with the data. With or without using a metastore.&lt;br&gt;
With the metastore, users can have access to the data in the Data Lake in an easier way because they can use SQL statements as they do in any other databases.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KAFTb0Mq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/inicqwio30qpl0x4bq2r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KAFTb0Mq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/inicqwio30qpl0x4bq2r.png" alt="Image description" width="800" height="393"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Authorization, direct access.
&lt;/h2&gt;

&lt;p&gt;Consumers run their notebooks or any other applications from their AWS accounts and consume data located in the producer’s account. &lt;/p&gt;

&lt;p&gt;These notebooks and applications run in Amazon virtual servers called Amazon EC2 instances, and for accessing the data located in AWS S3 in the producer’s account, they use IAM Roles (the permissions for accessing the data)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QozqZ2ce--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/09juuarv46cd5on6gt28.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QozqZ2ce--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/09juuarv46cd5on6gt28.png" alt="Image description" width="800" height="424"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  S3 bucket policy
&lt;/h3&gt;

&lt;p&gt;For example, for being able to access to the S3 bucket called &lt;code&gt;s3://producer&lt;/code&gt;, with the IAM Role with ARN &lt;code&gt;arn:aws:iam::ACCOUNT_CONSUMER:role/IAM_ROLE_CONSUMER&lt;/code&gt;, we can use the following AWS S3 bucket policy in the &lt;code&gt;s3://producer&lt;/code&gt; bucket:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pWh0hDJH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ladtrivevp9l0lrh0oaf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pWh0hDJH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ladtrivevp9l0lrh0oaf.png" alt="Image description" width="800" height="647"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Direct access
&lt;/h3&gt;

&lt;p&gt;Here, we are showing an example, where from a Databricks notebook using the above IAM Role and running in the consumer account, we are able to access data located in the producer’s account.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--byVEaHzD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a4czn5agezvot3zbrd9h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--byVEaHzD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a4czn5agezvot3zbrd9h.png" alt="Image description" width="800" height="712"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Can we do it better?
&lt;/h3&gt;

&lt;p&gt;With &lt;a href="https://docs.aws.amazon.com/glue/latest/dg/catalog-and-crawler.html"&gt;Glue Catalog as metastore&lt;/a&gt;, data in S3 can be accessed as if it was stored in a table with rows and columns.&lt;/p&gt;

&lt;p&gt;If we use tables instead of the direct access, we can grant permissions even at column level.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://aws.amazon.com/es/lake-formation/"&gt;Lake Formation&lt;/a&gt; provides its own permissions model that augments the IAM permissions model. This centrally defined permissions model enables fine-grained access to data stored in data lakes through a simple grant or revoke mechanism, much like a database. Lake Formation permissions are enforced using granular controls at the column, row, and cell-levels.&lt;/p&gt;
&lt;h2&gt;
  
  
  Authorization, Lake Formation.
&lt;/h2&gt;

&lt;p&gt;For using Lake Formation we will need the following elements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;An application running in some machine in an AWS account. For example, an AWS EC2 instance where a Spark notebook will be executed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A shared resource between the producer and consumer’s account. In this case we are sharing the S3 bucket called producer.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;An IAM Role with permissions for using the producer’s bucket.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Two AWS Glue Catalogues as metastores. The one in the consumer's account will be in charge of forwarding the table resolution to the metastore in the producer’s account. Both metastores are also shared between the two accounts.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tsQzll7---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4kf9b0vhgayf1hfxtc75.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tsQzll7---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4kf9b0vhgayf1hfxtc75.png" alt="Image description" width="800" height="330"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The catalogue in the producer’s account contains all the required information for translating the virtual table to its physical S3 location.&lt;/p&gt;

&lt;p&gt;In the below screenshots you can see the Lake Formation configuration for the Glue metastore located in the producer’s account. &lt;/p&gt;

&lt;p&gt;First you can see the table and database where the producer’s table is located. You can also see that we are sharing the specific table with the consumer’s account.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Database: schema
Table: producer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7TugteEC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pq3grmajm8yrt5frh2uu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7TugteEC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pq3grmajm8yrt5frh2uu.png" alt="Image description" width="800" height="573"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the above table we can configure access permissions. For example, we can decide that we will be allowing only the use of &lt;code&gt;SELECT&lt;/code&gt; statements from the consumer’s account and also the only column that will be shown is the one called &lt;code&gt;brand_id&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--buVHHBGt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fn3pafvce60y0pzyrssu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--buVHHBGt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fn3pafvce60y0pzyrssu.png" alt="Image description" width="800" height="438"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, from the Spark notebook running in the consumer’s account we can run SQL statements against the table located in the producer’s account.&lt;/p&gt;

&lt;p&gt;Because we only allowed access to the column called &lt;code&gt;brand_id&lt;/code&gt;, the consumer will only see values for that column. Any other column will be hidden.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--90aIq0ek--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/at1wvg6seyizk0u6esap.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--90aIq0ek--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/at1wvg6seyizk0u6esap.png" alt="Image description" width="800" height="290"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion.
&lt;/h2&gt;

&lt;p&gt;In this article we have explained how you can implement an authorization layer using AWS IAM Roles and AWS Lake Formation.&lt;/p&gt;

&lt;p&gt;With this authorization layer we will be able to resolve the following problems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Producers and consumers from different domains must have the capability of working in an isolated way (if they wish so) if we want to implement a data mesh with success.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Producers must be able to decide how consumers can access their data. They are the data owners, and they decide how others use their data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fine grained permissions can be established. At column and even if we want, at row level. This will be of great interest if we want to be &lt;a href="https://en.wikipedia.org/wiki/General_Data_Protection_Regulation"&gt;GDPR&lt;/a&gt; compliant. More information about how to implement the GDPR in your own data platform will be explained in future articles.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Stay tuned for the next article about how to implement your own Data Platform with success.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I hope this article was useful. If you enjoy messing around with Big Data, Microservices, reverse engineering or any other computer stuff and want to share your experiences with me, just follow &lt;a href="https://twitter.com/gumartinm"&gt;me&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>datamesh</category>
      <category>dataplatform</category>
      <category>datalake</category>
      <category>lakeformation</category>
    </item>
    <item>
      <title>How to build your own data platform. Episode 1: sharing data between environments. Data Warehouse implementation.</title>
      <dc:creator>Gustavo Martin Morcuende</dc:creator>
      <pubDate>Tue, 06 Dec 2022 00:27:50 +0000</pubDate>
      <link>https://dev.to/adevintaspain/how-to-build-your-own-data-platform-episode-1-sharing-data-between-environments-data-warehouse-implementation-4nko</link>
      <guid>https://dev.to/adevintaspain/how-to-build-your-own-data-platform-episode-1-sharing-data-between-environments-data-warehouse-implementation-4nko</guid>
      <description>&lt;h2&gt;
  
  
  Introduction.
&lt;/h2&gt;

&lt;p&gt;This article is the second part of the first episode about how to build your own data platform. To catch up, follow this link: &lt;a href="https://dev.to/adevintaspain/how-to-build-your-own-data-platform-4l6c"&gt;https://dev.to/adevintaspain/how-to-build-your-own-data-platform-4l6c&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As a short recap, remember that for creating a data platform many parts are involved. For this first episode we are only focusing on the component that we called storage layer. In the storage layer we could find the Lakehouse or Data Lake and the Data Warehouse. In the previous article we talked about how to share data in the Data Lake, in this second part we will be talking about the same but in the Data Warehouse.&lt;/p&gt;

&lt;h2&gt;
  
  
  Storage layer.
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FQ5xqutf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/19ifkap4g03ppz060no5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FQ5xqutf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/19ifkap4g03ppz060no5.png" alt="storage layer" width="880" height="313"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can see in this diagram three different elements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Data Lakehouse:&lt;/strong&gt; we already talked about it in the previous article.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Metastore:&lt;/strong&gt; also we explained it in the last article. We will talk about it more deeply in the coming articles.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Data Warehouse:&lt;/strong&gt; many times you will need to implement &lt;a href="https://en.wikipedia.org/wiki/Star_schema"&gt;star schemas&lt;/a&gt; for creating &lt;a href="https://en.wikipedia.org/wiki/Data_mart"&gt;data marts&lt;/a&gt;. Here, users can find meaningful data for creating dashboards, machine learning products or any other thing that users require. In this case, the Data Warehouse will be implemented on &lt;a href="https://aws.amazon.com/redshift/"&gt;AWS Redshift&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Current situation (environment isolation)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gvQG4qaF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fbep4wl6hfks7ffzetjg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gvQG4qaF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fbep4wl6hfks7ffzetjg.png" alt="current situation" width="880" height="594"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Remember that if you want users to create data products as fast as possible, you will need to create at least one environment where these users can mess around with the stored data. In this isolated environment they will be able to break and change as many things as they want. Our production environment must be isolated from this and other environments because we do not want to break productive processes.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem with data.
&lt;/h2&gt;

&lt;p&gt;We want users to be able to work with huge amounts of data in an easy and fast way, but we want them to do that in isolated environments from the productive one because we do not want them to break anything.&lt;/p&gt;

&lt;h2&gt;
  
  
  Data Warehouse, AWS Redshift.
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VaSkUBmG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rzoj2ui1lamfqvfjy9mm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VaSkUBmG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rzoj2ui1lamfqvfjy9mm.png" alt="data warehouse aws redshift" width="880" height="342"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All the environments have the same components but isolated one of each other.&lt;/p&gt;

&lt;p&gt;The Data Warehouse is implemented on the top of AWS Redshift. Not many years ago a new service was released by Amazon called &lt;a href="https://aws.amazon.com/redshift/features/ra3/"&gt;AWS Redshift RA3&lt;/a&gt;. What makes RA3 different from the old Redshift is that, in the new implementation, computation and storage are separated. Before having RA3, if users needed more storage capabilities, more computation had also to be paid even if computation was not a problem. And in the opposite way, when users needed more computation capabilities, more storage had to be paid. So, Redshift costs were typically high.&lt;/p&gt;

&lt;p&gt;Since the release of AWS Redshift RA3, because storage and computation are separated, users can decide if they want to increase either their storage or computational capabilities and only pay for what they need.&lt;/p&gt;

&lt;p&gt;We will be using AWS Redshift RA3. Here you can find some useful links that explain further what are AWS Redshift and AWS Redshift RA3:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://docs.aws.amazon.com/redshift/latest/mgmt/welcome.html"&gt;https://docs.aws.amazon.com/redshift/latest/mgmt/welcome.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/blogs/big-data/use-amazon-redshift-ra3-with-managed-storage-in-your-modern-data-architecture/"&gt;https://aws.amazon.com/blogs/big-data/use-amazon-redshift-ra3-with-managed-storage-in-your-modern-data-architecture/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Data Warehouse, Redshift RA3.
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AIqEGZr7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m88lbkztghbtsmf9ngm9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AIqEGZr7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m88lbkztghbtsmf9ngm9.png" alt="Image description" width="880" height="340"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With Redshift RA3 storage is located under the component called Redshift Managed Storage located in AWS S3. As you can see on the above diagram, compute nodes are separated from the storage.&lt;/p&gt;

&lt;p&gt;You can find more information about RA3 in the following link: &lt;a href="https://aws.amazon.com/blogs/big-data/use-amazon-redshift-ra3-with-managed-storage-in-your-modern-data-architecture/"&gt;https://aws.amazon.com/blogs/big-data/use-amazon-redshift-ra3-with-managed-storage-in-your-modern-data-architecture/&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Data Warehouse, integration and production environments.
&lt;/h2&gt;

&lt;p&gt;In the integration environment we work with data as you can see in the pictures below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--k4g_ne66--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9w3bnsf50fmd4nftntf9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--k4g_ne66--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9w3bnsf50fmd4nftntf9.png" alt="integration environment" width="880" height="624"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the production environment we have the exact same system but isolated from the integration environment. In production we find the exact same statements.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rkHqq7fW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rdgq5gtsnm9imr9mlapz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rkHqq7fW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rdgq5gtsnm9imr9mlapz.png" alt="production environment" width="880" height="625"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Data Warehouse, sharing data.
&lt;/h2&gt;

&lt;p&gt;AWS Redshift RA3 includes something called data sharing. With data sharing we can access with read only permissions to Redshift data located in other Redshift servers and even in different accounts or environments.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Data sharing provides instant, granular, and high-performance access without copying data and data movement. You can query live data constantly across all consumers on different RA3 clusters in the same AWS account, in a different AWS account, or in a different AWS Region. Queries accessing shared data use the compute resources of the consumer Amazon Redshift cluster and don’t impact the performance of the producer cluster.&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://aws.amazon.com/blogs/big-data/use-amazon-redshift-ra3-with-managed-storage-in-your-modern-data-architecture/"&gt;https://aws.amazon.com/blogs/big-data/use-amazon-redshift-ra3-with-managed-storage-in-your-modern-data-architecture/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://aws.amazon.com/blogs/big-data/announcing-amazon-redshift-data-sharing-preview/"&gt;https://aws.amazon.com/blogs/big-data/announcing-amazon-redshift-data-sharing-preview/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Data Sharing.
&lt;/h3&gt;

&lt;p&gt;With Data Sharing, we can configure the AWS Redshift in the integration environment for accessing the storage of the AWS Redshift located in the production environment.&lt;/p&gt;

&lt;p&gt;You can find more information about it in the following link: &lt;a href="https://aws.amazon.com/blogs/big-data/sharing-amazon-redshift-data-securely-across-amazon-redshift-clusters-for-workload-isolation/"&gt;https://aws.amazon.com/blogs/big-data/sharing-amazon-redshift-data-securely-across-amazon-redshift-clusters-for-workload-isolation/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RyBas7s6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xaxeqp18optazuuqc954.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RyBas7s6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xaxeqp18optazuuqc954.png" alt="data sharing" width="880" height="338"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Data Sharing, implementation.
&lt;/h3&gt;

&lt;p&gt;In order to create a data sharing between the integration and production AWS Redshift servers, you can follow the next steps.&lt;/p&gt;

&lt;p&gt;AWS Redshift RA3, production environment, statements to run:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CREATE DATASHARE meetup_sharing;&lt;/li&gt;
&lt;li&gt;GRANT USAGE ON DATASHARE meetup_sharing TO ACCOUNT 'INTEGRATION';&lt;/li&gt;
&lt;li&gt;ALTER DATASHARE meetup_sharing ADD SCHEMA schema;&lt;/li&gt;
&lt;li&gt;ALTER DATASHARE meetup_sharing SET INCLUDENEW = TRUE FOR SCHEMA schema;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AWS Redshift RA3, integration environment, statements to run:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CREATE DATABASE meetup_pro FROM DATASHARE meetup_sharing OF ACCOUNT 'PRODUCTION' &lt;/li&gt;
&lt;li&gt;CREATE EXTERNAL SCHEMA IF NOT EXISTS pro_schema FROM REDSHIFT DATABASE 'meetup_pro' SCHEMA 'schema';&lt;/li&gt;
&lt;li&gt;GRANT USAGE ON SCHEMA pro_schema TO schema;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With the above configuration, when using the &lt;strong&gt;pro_&lt;/strong&gt; prefix in the integration environment, we will be accessing data located in the production one. This access is read only, so we can not modify that data in any way.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FoRyIkv1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xv36ycjybfxv95fp83ge.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FoRyIkv1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xv36ycjybfxv95fp83ge.png" alt="data sharing implementation" width="880" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion.
&lt;/h2&gt;

&lt;p&gt;Through this article we have covered how to resolve the following problems in a Data Lake implemented in AWS S3:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Users (data engineers, data analysts and data scientists) need to work in pre-production environments with the same amount of data as in production.&lt;/li&gt;
&lt;li&gt;We want to have different and isolated environments: integration, production, etc.&lt;/li&gt;
&lt;li&gt;Users need to work with the data in the easiest possible way.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Stay tuned for the next article about how to implement your own Data Platform with success.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I hope this article was useful. If you enjoy messing around with Big Data, Microservices, reverse engineering or any other computer stuff and want to share your experiences with me, just follow &lt;a href="https://twitter.com/gumartinm"&gt;me&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>dataplatform</category>
      <category>datalake</category>
      <category>lakehouse</category>
      <category>datamesh</category>
    </item>
    <item>
      <title>How to build your own data platform. Episode 1: sharing data between environments. Data Lake implementation.</title>
      <dc:creator>Gustavo Martin Morcuende</dc:creator>
      <pubDate>Tue, 29 Nov 2022 01:06:07 +0000</pubDate>
      <link>https://dev.to/adevintaspain/how-to-build-your-own-data-platform-4l6c</link>
      <guid>https://dev.to/adevintaspain/how-to-build-your-own-data-platform-4l6c</guid>
      <description>&lt;h2&gt;
  
  
  Introduction.
&lt;/h2&gt;

&lt;p&gt;Data is the new oil. Companies want to make the most of the data they produce. For achieving this goal, there is a need for systems capable of consuming, processing, analysing, and presenting massive volumes of data. These systems need to be easy to use, but they also need to be reliable, able to detect problems and store data correctly. These and other issues are intended to be resolved by Data Platforms.&lt;/p&gt;

&lt;p&gt;It is not an easy task to build a Data Platform. Multiple skill sets are needed, from infrastructure and programming to data management.&lt;/p&gt;

&lt;p&gt;This article is the first, of what I hope will be a longer series of articles where we'll try to unravel the secrets of how to build a Data Platform that allows you to generate value-added products for your users. &lt;/p&gt;

&lt;h2&gt;
  
  
  What is a data platform?
&lt;/h2&gt;

&lt;p&gt;We can discover definitions of what is a data platform just using our preferred web search engine. For example, I found the following definitions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A data platform enables the acquisition, storage, preparation, delivery, and governance of your data, and adds a security layer for users and applications.&lt;br&gt;
&lt;a href="https://www.mongodb.com/what-is-a-data-platform" rel="noopener noreferrer"&gt;https://www.mongodb.com/what-is-a-data-platform&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A data platform is a complete solution for ingesting, processing, analyzing and presenting the data generated by the systems, processes and infrastructures of the modern digital organization.&lt;br&gt;
&lt;a href="https://www.splunk.com/en_us/data-insider/what-is-a-data-platform.html" rel="noopener noreferrer"&gt;https://www.splunk.com/en_us/data-insider/what-is-a-data-platform.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, a data platform is a place where we can store data from multiple sources. Also a data platform provides users with the required tools for searching, working and transforming that data, with the goal of creating some kinds of products. These products could be dashboards with useful insights, machine learning products, etc, etc.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a data platform? Very simplified diagram.
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6bpq3juhhmddhzcma5wj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6bpq3juhhmddhzcma5wj.png" alt="Data Platform simplified diagram" width="800" height="268"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this diagram we can find all the basic components that create a data platform (we are not trying to describe a &lt;a href="https://en.wikipedia.org/wiki/Data_mesh" rel="noopener noreferrer"&gt;Data Mesh&lt;/a&gt; or a &lt;a href="https://en.wikipedia.org/wiki/Data_management_platform" rel="noopener noreferrer"&gt;Data Management Platform&lt;/a&gt;, those things will be left out for other future articles) You can find the same components with other names but same functionality in other diagrams describing other data platforms. In this diagram we can find these components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Data Sources:&lt;/strong&gt; databases, REST APIs, event buses, analytics tools, etc, etc.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Consumption:&lt;/strong&gt; tools for consuming the data sources.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Storage:&lt;/strong&gt; the place where the consumed data will be located.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Security layer:&lt;/strong&gt; component in charge of providing authentication, authorization and auditory.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Processing:&lt;/strong&gt; programs or tools that will enable us to work with the stored data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Data Catalog:&lt;/strong&gt;  because the amount of stored data will be huge, we need a tool that will make easy for users to find the data that they need.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Tableau, Qlik, Kubeflow, MLflow, etc, etc:&lt;/strong&gt; data will be used for some goal. Typically this goal could be to create a dashboard with meaningful diagrams, create models for machine learning and many other things.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This first article will be focusing on the storage layer, so from now on, we will talk only about that component.&lt;/p&gt;

&lt;h2&gt;
  
  
  Storage layer.
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyv8h616qadlfl8xnzglu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyv8h616qadlfl8xnzglu.png" alt="storage layer" width="800" height="295"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Of course, the storage layer is the place where the data is stored. Because the amount of data to be stored is huge, we can not use HDD or SSD data storages, we need something cheaper. In this case we will be talking about &lt;a href="https://aws.amazon.com/s3/" rel="noopener noreferrer"&gt;AWS S3&lt;/a&gt; because we are working with &lt;a href="https://en.wikipedia.org/wiki/Amazon_Web_Services" rel="noopener noreferrer"&gt;Amazon Web Services&lt;/a&gt;. For &lt;a href="https://en.wikipedia.org/wiki/Microsoft_Azure" rel="noopener noreferrer"&gt;Azure&lt;/a&gt;, you could use &lt;a href="https://learn.microsoft.com/en-us/azure/storage/blobs/data-lake-storage-introduction" rel="noopener noreferrer"&gt;Azure Data Lake Storage Gen2&lt;/a&gt;. If you are working with &lt;a href="https://en.wikipedia.org/wiki/Google_Cloud_Platform" rel="noopener noreferrer"&gt;Google Cloud&lt;/a&gt;, you could use &lt;a href="https://cloud.google.com/storage" rel="noopener noreferrer"&gt;Google Cloud Storage&lt;/a&gt;. It does not matter what storage you use as long as it is cheap and can store a huge amount of data.&lt;/p&gt;

&lt;p&gt;You can see in this diagram three different elements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Data Lakehouse:&lt;/strong&gt; it is the evolution of the traditional Data Lake. Data Lakehouse implements all the capabilities of a Data Lake plus ACID transactions. You can find more information about Lakehouses in this &lt;a href="https://www.databricks.com/glossary/data-lakehouse" rel="noopener noreferrer"&gt;link&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Usually in a Data Lakehouse or a Data Lake you can find different zones for storing data. The number of zones that you can find depends on how you want to classify your data. How to create and classify the data in your Data Lake or Lakehouse is a complicated matter that will be treated in a future article. The Data Lake is the first place where the consumed data is stored. Sometimes it is just meaningless raw data.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Data Warehouse:&lt;/strong&gt; many times you will need to implement &lt;a href="https://en.wikipedia.org/wiki/Star_schema" rel="noopener noreferrer"&gt;star schemas&lt;/a&gt; for creating &lt;a href="https://en.wikipedia.org/wiki/Data_mart" rel="noopener noreferrer"&gt;data marts&lt;/a&gt; in order to make easy for users the use of the stored data. Here, users can find meaningful data for creating dashboards, machine learning products or any other thing that users require.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Metastore:&lt;/strong&gt; data is stored in the blob storage, if you want to use this data as if it was stored in a traditional database we need an element for translating schemas and table names to folders and files in the blob storage. This translation is made by the metastore.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This article does not try to deeply explain how the above three elements work. Those explanations will be left out for other future articles.&lt;/p&gt;

&lt;h2&gt;
  
  
  Current situation (environment isolation)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fccaa5e1n1ak9gubjql5c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fccaa5e1n1ak9gubjql5c.png" alt="Current situation" width="800" height="540"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you want users to create data products as fast as possible, you will need to create at least one environment where these users can mess around with the stored data. In this isolated environment they will be able to break and change as many things as they want. Our production environment must be isolated from this and other environments because we do not want to break productive processes. Different and isolated environments will exist. These environments contain the same processing and storage layers but these layers are isolated in their own environments. So notebooks in the sandbox environment can not break data stored in the storage layer from the production environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem with data.
&lt;/h2&gt;

&lt;p&gt;Data engineers, data analysts, data scientists and data people in general who work with big data require huge amounts of data in order to implement, develop and test their applications. These applications could be ETLs, ELTs, notebooks, dashboards, etc, etc.&lt;/p&gt;

&lt;p&gt;In a healthy system, these users should be able to work in a safe environment where they can be sure &lt;strong&gt;that they do not break anything that already works in production when trying to implement new solutions.&lt;/strong&gt; We need to create isolated environments. These environments could be sandbox, integration, production environment, etc, etc.&lt;br&gt;
The problem with having different and isolated environments is that, in no productive environments, the amount of data will probably be much lower than the one that will be generated in production.&lt;/p&gt;

&lt;p&gt;So now, we face the following problem: &lt;strong&gt;we want users to be able to work with huge amounts of data in an easy and fast way, but we want them to do that in isolated environments from the productive one because we do not want them to break anything.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The solution 1.
&lt;/h2&gt;

&lt;p&gt;Remember that we have data sources, and those data sources must be connected to our different and isolated environments. We could ask those data sources to send us the same amount of data as they are sending in the productive environment.&lt;/p&gt;

&lt;p&gt;The problem with this solution is that, in many cases, those data sources have their own no preproductive environments and it is impossible for them to generate the same amount of data in the rest of the environments as in the production environment. Also, they will not be willing to connect our own no preproductive environments to their productive ones because we could break their environments.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faqlt7t9fgb85zg0nh9e0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faqlt7t9fgb85zg0nh9e0.png" alt="the solution 1" width="800" height="431"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This solution in many cases will not work.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The solution 2.
&lt;/h2&gt;

&lt;p&gt;Another solution could be as simple as implementing a job for copying data from the storage located in the productive environment to the no productive one. For example, a Jenkins job.&lt;/p&gt;

&lt;p&gt;The problem with this solution is that copying huge amounts of data is not fast and also, the job can break easily for multiple reasons (not having the right permissions, the right amount of memory for moving all the required data, etc, etc)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh4jwqdefqo3wh0hi5yma.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh4jwqdefqo3wh0hi5yma.png" alt="the solution 2" width="800" height="335"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This solution does not ease the development of new applications because the copying process is slow, sometimes will not work, and data is not immediately available.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The solution 3.
&lt;/h2&gt;

&lt;p&gt;What our users need is to have access to data generated in the production environment from the tools running in the no productive environments. We need to provide a solution where applications like notebooks running in for example the integration environment can access the storage located in the productive one.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiuz5j2qhr6vpue2uduq6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiuz5j2qhr6vpue2uduq6.png" alt="the solution 3" width="800" height="508"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This solution will work in all cases. This is the solution that we are going to explain in this article focusing on the component related to the Data Lake. In a next article we will explain the same solution implemented in a Data Warehouse.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Data Lake, AWS S3.
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frry6ez0gwlkpx6vrdtkg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frry6ez0gwlkpx6vrdtkg.png" alt="data lake aws s3" width="800" height="317"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Notebooks, Spark jobs, clusters, etc, etc, run in Amazon virtual servers called &lt;a href="https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/concepts.html" rel="noopener noreferrer"&gt;EC2&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;These virtual servers require permissions for accessing AWS S3. These permissions are given by &lt;a href="https://docs.aws.amazon.com/IAM/latest/UserGuide/introduction.html" rel="noopener noreferrer"&gt;IAM Roles&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We will be working with Amazon Web Services. As we said before, because the amount of data to be stored is huge, we can not use HDD or SSD data storages, we need something cheaper. In this case we will be talking about &lt;a href="https://aws.amazon.com/s3/" rel="noopener noreferrer"&gt;AWS S3&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Also, in order to make easy the use of the Data Lake, we can implement &lt;a href="https://www.quora.com/What-is-hive-meta-store/answer/Shruti-Pawar-9" rel="noopener noreferrer"&gt;metastores&lt;/a&gt; on the top of it. For example, Hive Metastore or Glue Catalog. We are not going to explain deeply how a metastore works, that will be left for another future article.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When using a notebook (for example a Databricks notebook) and having a metastore, the first thing that the notebook will do is to ask the metastore where the data is physically located. Once the metastore responds, the notebook will go to the path in AWS S3 where the data is stored using the permissions given by the IAM Role.&lt;/p&gt;

&lt;h2&gt;
  
  
  Data Lake, integration and production environments.
&lt;/h2&gt;

&lt;p&gt;In the integration environment we have two options for working with the data. With or without using a metastore.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fceeo319vjd2zbv25ue14.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fceeo319vjd2zbv25ue14.png" alt="data lake integration metastore" width="800" height="385"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the production environment we have the exact same system but isolated from the integration environment. In production we find the exact same two options.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmh3a9ju0ppi0et4gqh64.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmh3a9ju0ppi0et4gqh64.png" alt="Image description" width="800" height="385"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, the metastore allows us to use the data located in the Data Lake as it was a normal database. Also, we can see that the metastore does not store data but the metadata that allows us to find the real stored data in AWS S3. With the metastore, users can have access to the data in the Data Lake in an easier way because they can use SQL statements as they do in any other database.&lt;/p&gt;

&lt;h2&gt;
  
  
  Data Lake, sharing data.
&lt;/h2&gt;

&lt;p&gt;When users run their notebooks or any other application from the integration environment they need to have access to the production data located in the storage zone of the production environment.&lt;/p&gt;

&lt;p&gt;Remember that those notebooks and applications run in Amazon virtual servers called Amazon EC2 instances, and for accessing the data located in AWS S3 they use IAM Roles (the permissions for accessing the data) We can modify the IAM Role in the (for example) integration environment in order to allow EC2 instances to access data located in the productive storage zone.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmttrjn9x4lwasx833oxn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmttrjn9x4lwasx833oxn.png" alt="data lake sharing data" width="800" height="841"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  IAM Role configuration.
&lt;/h3&gt;

&lt;p&gt;For example, for being able to access to S3 integration and production folders we can configure the IAM Role in the following way:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwwdqel5iyw3ejvha2t30.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwwdqel5iyw3ejvha2t30.png" alt="IAM Role" width="800" height="544"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Any application running on a machine with this IAM Role can read data from production and integration and can only modify the data located in the integration environment. So the productive data is not modified in any way.&lt;/p&gt;

&lt;h3&gt;
  
  
  Applying the solution.
&lt;/h3&gt;

&lt;p&gt;Once we have applied the above configuration in the IAM Role, users have direct access to the data located in the productive environment, for example from the integration environment.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmckirq5sqi0xecxxqcvj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmckirq5sqi0xecxxqcvj.png" alt="applying solution" width="800" height="396"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Can we do it better?
&lt;/h3&gt;

&lt;p&gt;With this configuration users, from for example their notebooks, can access the productive data and work with it without being able to modify it. But, we know, by means of a metastore, users can access the data even in an easier way. So the question is: can we use metastores with this solution?&lt;/p&gt;

&lt;p&gt;We will see how to do it in the next section of this article.&lt;/p&gt;

&lt;h2&gt;
  
  
  Data Lake, sharing data. Waggle Dance.
&lt;/h2&gt;

&lt;p&gt;Waggle Dance is a request routing Hive metastore proxy that allows tables to be concurrently accessed across multiple Hive deployments.&lt;/p&gt;

&lt;p&gt;In short, Waggle Dance provides a unified endpoint with which you can describe, query, and join tables that may exist in multiple distinct Hive deployments. Such deployments may exist in disparate regions, accounts, or clouds (security and network permitting).&lt;/p&gt;

&lt;p&gt;For further information follow this link: &lt;a href="https://github.com/ExpediaGroup/waggle-dance" rel="noopener noreferrer"&gt;https://github.com/ExpediaGroup/waggle-dance&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4fmbntehg6p0ok77n5dg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4fmbntehg6p0ok77n5dg.png" alt="data lake waggle dance" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, when asking for some table from the integration environment, and based on some configuration, the Waggle Dance living in the integration environment decides if the metastore to be asked resides either in the production or integration environment.&lt;/p&gt;

&lt;p&gt;For example, this configuration could be based on some prefix. In the below example, the &lt;strong&gt;pro_&lt;/strong&gt;prefix. When using this prefix the data to be retrieved will be located in the production environment instead of the integration one.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc41r9jt6hx0pluvfi781.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc41r9jt6hx0pluvfi781.png" alt="using data lake waggle dance" width="800" height="410"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion.
&lt;/h2&gt;

&lt;p&gt;Through this article we have covered how to resolve the following problems in a Data Lake implemented in AWS S3:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Users (data engineers, data analysts and data scientists) need to work in pre-production environments with the same amount of data as in production.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We want to have different and isolated environments: integration, production, etc.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Users need to work with the data in the easiest possible way.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Stay tuned for the next article about how to share data with AWS Redshift and many others that will follow about how to implement your own Data Platform with success.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I hope this article was useful. If you enjoy messing around with Big Data, Microservices, reverse engineering or any other computer stuff and want to share your experiences with me, just follow &lt;a href="https://twitter.com/gumartinm" rel="noopener noreferrer"&gt;me&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>cybersecurity</category>
      <category>softwaredevelopment</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Spark: unit, integration and end-to-end tests.</title>
      <dc:creator>Gustavo Martin Morcuende</dc:creator>
      <pubDate>Thu, 15 Oct 2020 07:15:25 +0000</pubDate>
      <link>https://dev.to/adevintaspain/spark-unit-integration-and-end-to-end-tests-f52</link>
      <guid>https://dev.to/adevintaspain/spark-unit-integration-and-end-to-end-tests-f52</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4j58hvbozn9gebv0lqrj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4j58hvbozn9gebv0lqrj.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;At Adevinta Spain we are building a Data Platform where we use multiple applications and frameworks some of them based on Spark.&lt;/p&gt;

&lt;p&gt;In order to increase the quality of our Spark applications we wanted to run tests in the same way as we did with other frameworks. What means, we wanted to be able to run unit, integration and end-to-end tests.&lt;/p&gt;

&lt;p&gt;This article explains the way Spark tests are run at Adevinta Spain. Hopefully, it will be useful for other big data developers searching ways to improve the quality of their code and at the same time their CI pipelines.&lt;/p&gt;

&lt;h1&gt;
  
  
  Unit, integration and end-to-end tests.
&lt;/h1&gt;

&lt;p&gt;When working with Spark, developers usually will be facing the need of implementing these kinds of tests. Other tests like smoke tests, acceptance tests, etc, etc are outside the scope of this article so I will not be mentioning them.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Unit Tests:&lt;/strong&gt; at this level we will be dealing with code that does not require a Spark Session in order to work. Also, this kind of code does not talk with the outside world.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Integration Tests:&lt;/strong&gt; at some point we will need to use a Spark Session. At this level we will be testing Spark transformations and in many cases we will have to deal with external systems such as databases, Kafka clusters, etc, etc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;End-to-end Tests:&lt;/strong&gt; our application probably will be composed of several Spark transformations working together in order to implement some feature required by some user. Here, we will be testing the whole application.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Spark project layout
&lt;/h1&gt;

&lt;p&gt;This is a typical scala project layout. I think this layout should work under any use case but if it does not work for you, at least I hope, it will bring some inspiration or ideas to your testing implementation.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

src/
├── main
│   └── scala
│       └── example
│           ├── app
│           │   └── AwesomeApp.scala
│           ├── job
│           │   └── AwesomeJob.scala
│           └── service
│               └── AwesomeService.scala
└── test
    ├── resources
    │   ├── awesomejob
    │   │   └── sourcepath
    │   │       └── awesome.json
    │   └── log4j.properties
    └── scala
        └── example
            ├── app
            │   └── AwesomeAppEndToEndTest.scala
            ├── job
            │   └── AwesomeJobIntegrationTest.scala
            ├── service
            │   └── AwesomeServiceTest.scala
            └── SharedSparkSessionHelper.scala


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h1&gt;
  
  
  Application layout
&lt;/h1&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;app package&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Under this package we will find the classes in charge of running our Spark applications. Typically we will have only one Spark application.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;job package&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;A Spark application should implement some kind of transformations. Modules under this package run Spark jobs that require a Spark Session.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;service package&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Sometimes business logic does not require a Spark Session in order to work. In such cases, we can implement the logic in a different module.&lt;/p&gt;
&lt;h1&gt;
  
  
  Shared Spark Session
&lt;/h1&gt;

&lt;p&gt;One of the biggest problems to be solved when running Spark tests is the isolation of these tests. Running a test should not affect the results of another. In order to achieve this goal we are going to need a Spark Session for each set of tests, in this way, the results of these tests will not affect others that will also require a Spark Session.&lt;/p&gt;

&lt;p&gt;So, we need to implement a system that will enable us to run, clear and stop a Spark Session whenever we need it (before and after a set of related Spark tests)&lt;/p&gt;

&lt;p&gt;The details of the implementation are explained down below:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;beforeAll:&lt;/strong&gt; &lt;em&gt;&lt;a href="https://www.scalatest.org/scaladoc/1.0/org/scalatest/BeforeAndAfterAll.html" rel="noopener noreferrer"&gt;beforeAll&lt;/a&gt;&lt;/em&gt; is a scala test function that runs before any other test in our class under test. We will be using this function for starting our Spark Session.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;sparkConf:&lt;/strong&gt; &lt;em&gt;sparkConf&lt;/em&gt; function enables us to load different Spark Sessions with different Spark configurations.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;embedded hive:&lt;/strong&gt; &lt;em&gt;spark-warehouse&lt;/em&gt; and &lt;em&gt;metastore_db&lt;/em&gt; are folders used by Spark when enabling the Hive support. Different Spark Sessions in the same process can not use the same folders. Because of that, we need to create random folders in every Spark Session. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;a href="http://doc.scalatest.org/1.0/org/scalatest/BeforeAndAfterEach.html" rel="noopener noreferrer"&gt;beforeEach&lt;/a&gt;:&lt;/strong&gt; scala test function that creates a temporary path which is useful when our Spark tests end up writing results in some location.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;a href="http://doc.scalatest.org/1.0/org/scalatest/BeforeAndAfterEach.html" rel="noopener noreferrer"&gt;afterEach&lt;/a&gt;:&lt;/strong&gt; clears and resets the Spark Session at the end of every test. Also, it removes the temporary path.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.scalatest.org/scaladoc/1.0/org/scalatest/BeforeAndAfterAll.html" rel="noopener noreferrer"&gt;afterAll&lt;/a&gt;:&lt;/strong&gt; stops the current Spark Session after the set of tests are run. In this way we will be able to run a new Spark Session if it is needed (if there is another set of tests requiring the use of Spark)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  How it works
&lt;/h1&gt;

&lt;p&gt;The basic idea behind &lt;em&gt;SharedSparkSessionHelper&lt;/em&gt; lies in the fact that there is one Spark Session per Java process and it is stored in an &lt;em&gt;&lt;a href="https://docs.oracle.com/javase/8/docs/api/java/lang/InheritableThreadLocal.html" rel="noopener noreferrer"&gt;InheritableThreadLocal&lt;/a&gt;&lt;/em&gt;. When calling &lt;em&gt;&lt;a href="https://spark.apache.org/docs/latest/api/java/org/apache/spark/sql/SparkSession.Builder.html" rel="noopener noreferrer"&gt;getOrCreate&lt;/a&gt;&lt;/em&gt; method from &lt;em&gt;SparkSession.Builder&lt;/em&gt; we end up either creating a new Spark Session (and storing it in the InheritableThreadLocal) or using an existing one.&lt;/p&gt;

&lt;p&gt;So, for example, when running an end-to-end test, because &lt;em&gt;SharedSparkSessionHelper&lt;/em&gt; is loaded before anything else (by means of the &lt;em&gt;beforeAll&lt;/em&gt; method), the application under test will be using the Spark Session launched by &lt;em&gt;SharedSparkSessionHelper&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Once the test class is finished, the &lt;em&gt;afterAll&lt;/em&gt; method stops the Spark Session and removes it from the &lt;em&gt;InheritableThreadLocal&lt;/em&gt; leaving our test environment ready for a new Spark Session. In this way, tests using Spark can run in an isolated way.&lt;/p&gt;

&lt;h1&gt;
  
  
  Awesome project
&lt;/h1&gt;

&lt;p&gt;This article would be nothing without a real example. Just following this &lt;a href="https://github.com/gumartinm/spark-shared-spark-session-helper" rel="noopener noreferrer"&gt;link&lt;/a&gt; you will find a project with &lt;a href="https://www.scala-sbt.org/" rel="noopener noreferrer"&gt;sbt&lt;/a&gt;, &lt;a href="https://www.scalatest.org/" rel="noopener noreferrer"&gt;scalatest&lt;/a&gt;, &lt;a href="http://www.scalastyle.org/" rel="noopener noreferrer"&gt;scalastyle&lt;/a&gt;, &lt;a href="https://github.com/scoverage/sbt-scoverage" rel="noopener noreferrer"&gt;sbt-coverage&lt;/a&gt; and &lt;a href="https://scalameta.org/scalafmt/" rel="noopener noreferrer"&gt;scalafmt&lt;/a&gt; where I use the SharedSparkSessionHelper trait.&lt;/p&gt;

&lt;p&gt;This application can be run in any of the available clusters that currently exist such as &lt;a href="https://kubernetes.io/" rel="noopener noreferrer"&gt;Kubernetes&lt;/a&gt;, &lt;a href="https://hadoop.apache.org/docs/current/hadoop-yarn/hadoop-yarn-site/YARN.html" rel="noopener noreferrer"&gt;Apache Hadoop Yarn&lt;/a&gt;, Spak running in &lt;a href="https://spark.apache.org/docs/2.4.5/cluster-overview.html" rel="noopener noreferrer"&gt;cluster mode&lt;/a&gt; or any other of your choice.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Testing Spark applications can seem more complicated than with other frameworks not only because of the need of preparing a data set but also because of the lack of tools that allow us to automate such tests. By means of the SharedSparkSessionHelper trait we can automate our tests in an easy way.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I hope this article was useful. If you enjoy messing around with Big Data, Microservices, reverse engineering or any other computer stuff and want to share your experiences with me, just follow &lt;a href="https://twitter.com/gumartinm" rel="noopener noreferrer"&gt;me&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>scala</category>
      <category>spark</category>
      <category>testing</category>
    </item>
  </channel>
</rss>
