<?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>Forem: JoeHo</title>
    <description>The latest articles on Forem by JoeHo (@joeho888).</description>
    <link>https://forem.com/joeho888</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%2F898791%2F45f997a8-d1da-4ce2-9420-88834130fd25.png</url>
      <title>Forem: JoeHo</title>
      <link>https://forem.com/joeho888</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/joeho888"/>
    <language>en</language>
    <item>
      <title>Disable anonymous bind for OpenLDAP in Centos7</title>
      <dc:creator>JoeHo</dc:creator>
      <pubDate>Thu, 13 Jul 2023 13:34:24 +0000</pubDate>
      <link>https://forem.com/joeho888/disable-anonymous-bind-for-openldap-in-centos7-1pmo</link>
      <guid>https://forem.com/joeho888/disable-anonymous-bind-for-openldap-in-centos7-1pmo</guid>
      <description>&lt;p&gt;LDAP bind is a process which the client tries to authenticate themselves to the server. Depends on the server set up, such bind request sent from client may contain no credentials (i.e. anonymous bind).&lt;/p&gt;

&lt;p&gt;In this guide, I will share how to configure the LDAP bind feature.&lt;/p&gt;

&lt;p&gt;Concept&lt;br&gt;
Before diving into the configuration, it’s better to know the types of LDAP bind.&lt;/p&gt;

&lt;p&gt;Anonymous bind&lt;br&gt;
Anonymous bind is that you present no distinguished name (you may treat it as an account name) and password in the bind request, the LDAP server will treat you as an anonymous. Usually, we will combine it with LDAP Access Control (ACL) to prevent anonymous from knowing some sensitive data if you decide to open part of the LDAP data to the public.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wgMkt_v_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://joeho.xyz/static/9f45fa993cf2b1170cedbece161f8435/f21e7/anonymous-bind.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wgMkt_v_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://joeho.xyz/static/9f45fa993cf2b1170cedbece161f8435/f21e7/anonymous-bind.png" alt="Anonymous bind" width="360" height="55"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Unauthenticated bind&lt;br&gt;
Unauthenticated bind allows you to present distinguished name and no password. By default, it’s disabled, as many applications don’t realize that they can still bind to LDAP server with incorrect password.&lt;/p&gt;

&lt;p&gt;Authenticated bind&lt;br&gt;
Authenticated bind requires the client to provide distinguished name and password.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oXik1Not--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://joeho.xyz/static/78cdac773420763569a43a7ac1498676/3e286/authenticated-bind.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oXik1Not--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://joeho.xyz/static/78cdac773420763569a43a7ac1498676/3e286/authenticated-bind.png" alt="Authenticated bind" width="523" height="55"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Disable anonymous bind for OpenLDAP&lt;br&gt;
By default, you can query LDAP data as an anonymous&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ldapsearch -LLL -x -b "dc=abc,dc=local" '(uid=joe)'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_cjlEsiF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://joeho.xyz/static/0b37b65bc96438cfa38e1363ccbe9dac/3c024/anonymous-query.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_cjlEsiF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://joeho.xyz/static/0b37b65bc96438cfa38e1363ccbe9dac/3c024/anonymous-query.png" alt="Anonymous query" width="573" height="314"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, we will disable it. Create a disable_bind_anon.ldif with below content&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dn: cn=config
changetype: modify
add: olcDisallows
olcDisallows: bind_anon
Apply the configuration
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo ldapadd -Y EXTERNAL -H ldapi:/// -f disable_bind_anon.ldif
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we try again, we can no longer query the user&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ldapsearch -LLL -x -b "dc=abc,dc=local" '(uid=joe)'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--erRhhuQB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://joeho.xyz/static/f6eebf0341572a4516b7b0bd4dcbe56b/508ef/disallowed-anonymous-query.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--erRhhuQB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://joeho.xyz/static/f6eebf0341572a4516b7b0bd4dcbe56b/508ef/disallowed-anonymous-query.png" alt="Disallowed anonymous query" width="578" height="58"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Conclusion&lt;br&gt;
In this guide, we discuss what bind is, types of bind and how to disable anonymous bind.&lt;/p&gt;

&lt;p&gt;Original Post: &lt;a href="https://joeho.xyz/blog-posts/disable-anonymous-bind-for-openldap-in-centos7/"&gt;Disable anonymous bind for OpenLDAP in Centos7 | Joe Ho Blog&lt;/a&gt;&lt;/p&gt;

</description>
      <category>linux</category>
      <category>devops</category>
      <category>cloud</category>
      <category>ubuntu</category>
    </item>
    <item>
      <title>Install and configure OpenLDAP server in CentOS 7</title>
      <dc:creator>JoeHo</dc:creator>
      <pubDate>Fri, 30 Sep 2022 13:38:46 +0000</pubDate>
      <link>https://forem.com/joeho888/install-and-configure-openldap-server-in-centos-7-3aff</link>
      <guid>https://forem.com/joeho888/install-and-configure-openldap-server-in-centos-7-3aff</guid>
      <description>&lt;p&gt;LDAP, Lightweight Directory Access Protocol is a directory service for us to manage identities and objects easily. One of the most common application is that you can authenticate to a server with LDAP. In Windows world, the server is usually Active Directory. In Linux world, OpenLDAP is widely adopted.&lt;/p&gt;

&lt;p&gt;In this guide, I will show you how to install and configure a simple workable LDAP server.&lt;/p&gt;

&lt;h2&gt;
  
  
  Concept
&lt;/h2&gt;

&lt;p&gt;Before diving into the installation and configuration, it's better to know some terms used in LDAP.&lt;/p&gt;

&lt;h3&gt;
  
  
  Attribute
&lt;/h3&gt;

&lt;p&gt;An attribute is a characteristic of an object. For example, an email of an account.&lt;/p&gt;

&lt;h3&gt;
  
  
  Object Class
&lt;/h3&gt;

&lt;p&gt;An object class defines what attributes that object can have. For example, we define an object class, InetOrgPerson, it may contain displayName and mail &lt;strong&gt;attributes&lt;/strong&gt;. Depends on the definition of object class, the attributes specified can be mandatory or optional.&lt;/p&gt;

&lt;h3&gt;
  
  
  Distinguished Name (DN)
&lt;/h3&gt;

&lt;p&gt;Distinguished Name lets us uniquely identify the object. It is similar to the file path in a reverse order. For example, &lt;strong&gt;uid=joeho,OU=People,DC=abc,DC=local&lt;/strong&gt; is a &lt;strong&gt;DN&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Entry
&lt;/h3&gt;

&lt;p&gt;An entry is just an object. You define what object class this entry belongs to &amp;amp; each object class defines what attributes this object has. Each entry can belong to multiple object classes and need to have all mandatory attributes specified in all object classes it belongs to.&lt;/p&gt;

&lt;h3&gt;
  
  
  Schema
&lt;/h3&gt;

&lt;p&gt;A schema contains the definitions of various attributes and object classes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Domain Component (DC) &amp;amp; Organizational Unit (OU)
&lt;/h3&gt;

&lt;p&gt;They are containers, contains object &amp;amp; let you manage objects in a hierarchy manner. People use them commonly.&lt;/p&gt;

&lt;h2&gt;
  
  
  OpenLDAP Installation
&lt;/h2&gt;

&lt;p&gt;Install OpenLDAP related packages&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;yum &lt;span class="nb"&gt;install &lt;/span&gt;openldap&lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl start slapd
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;slapd
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl status slapd &lt;span class="c"&gt;# Check service is started &amp;amp; enabled&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&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%2Fuploads%2Farticles%2Fldfv8aim8frbawvzo4s6.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%2Fuploads%2Farticles%2Fldfv8aim8frbawvzo4s6.png" alt="OpenLDAP Installation"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  OpenLDAP Configuration
&lt;/h2&gt;

&lt;p&gt;Generate OpenLDAP password and save it&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;slappasswd
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&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%2Fuploads%2Farticles%2F5i4mbyew19q0pfcihk2j.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%2Fuploads%2Farticles%2F5i4mbyew19q0pfcihk2j.png" alt="Generate OpenLDAP password"&gt;&lt;/a&gt;&lt;br&gt;
Then, we will use ldapmodify to update &lt;strong&gt;/etc/openldap/slapd.d/cn=config/olcDatabase={2}hdb.ldif&lt;/strong&gt;, which is our database config file&lt;br&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%2Fuploads%2Farticles%2Fick1cqyvcmalndi5f57t.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%2Fuploads%2Farticles%2Fick1cqyvcmalndi5f57t.png" alt="Original OpenLDAP configuration"&gt;&lt;/a&gt;&lt;br&gt;
We will create a file &amp;amp; customize and paste content below&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vi db.ldif
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Content you should paste:&lt;br&gt;
You should replace with your customized values&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;olcSuffix (should be replaced by your domain, e.g. example.com -&amp;gt; dc=example,dc=com)&lt;/li&gt;
&lt;li&gt;olcRootDN (should be replaced by your domain admin name, can be any name you prefer, e.g. admin -&amp;gt; cn=admin,dc=abc,dc=local)&lt;/li&gt;
&lt;li&gt;olcRootPW (should be the password you generate above)
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dn: &lt;span class="nv"&gt;olcDatabase&lt;/span&gt;&lt;span class="o"&gt;={&lt;/span&gt;2&lt;span class="o"&gt;}&lt;/span&gt;hdb,cn&lt;span class="o"&gt;=&lt;/span&gt;config
changetype: modify
replace: olcSuffix
olcSuffix: &lt;span class="nv"&gt;dc&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;abc,dc&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;local

&lt;/span&gt;dn: &lt;span class="nv"&gt;olcDatabase&lt;/span&gt;&lt;span class="o"&gt;={&lt;/span&gt;2&lt;span class="o"&gt;}&lt;/span&gt;hdb,cn&lt;span class="o"&gt;=&lt;/span&gt;config
changetype: modify
replace: olcRootDN
olcRootDN: &lt;span class="nv"&gt;cn&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;admin,dc&lt;span class="o"&gt;=&lt;/span&gt;abc,dc&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;local

&lt;/span&gt;dn: &lt;span class="nv"&gt;olcDatabase&lt;/span&gt;&lt;span class="o"&gt;={&lt;/span&gt;2&lt;span class="o"&gt;}&lt;/span&gt;hdb,cn&lt;span class="o"&gt;=&lt;/span&gt;config
changetype: modify
replace: olcRootPW
olcRootPW: &lt;span class="o"&gt;{&lt;/span&gt;SSHA&lt;span class="o"&gt;}&lt;/span&gt;xxxxx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&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%2Fuploads%2Farticles%2Fq52b7udrg1m2beaq3uq8.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%2Fuploads%2Farticles%2Fq52b7udrg1m2beaq3uq8.png" alt="OpenLDAP configuration modified"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Run this command to update.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;ldapmodify &lt;span class="nt"&gt;-Y&lt;/span&gt; External &lt;span class="nt"&gt;-H&lt;/span&gt; ldapi:/// &lt;span class="nt"&gt;-f&lt;/span&gt; db.ldif
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Configuration of &lt;strong&gt;/etc/openldap/slapd.d/cn=config/olcDatabase={2}hdb.ldif&lt;/strong&gt; should change&lt;/p&gt;

&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%2Fuploads%2Farticles%2F5k6uqmzllrj7dr8k0mah.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%2Fuploads%2Farticles%2F5k6uqmzllrj7dr8k0mah.png" alt="New OpenLDAP configuration"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Apply some &lt;a href="https://www.openldap.org/doc/admin24/schema.html#:~:text=13.1.-,Distributed%20Schema%20Files,-OpenLDAP%20Software%20is" rel="noopener noreferrer"&gt;commonly used schema&lt;/a&gt;. The 2nd &amp;amp; 3rd schema allow us to create an object with InetOrgPerson &amp;amp; ShadowAccount which we will use to create an user&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;ldapadd &lt;span class="nt"&gt;-Y&lt;/span&gt; EXTERNAL &lt;span class="nt"&gt;-H&lt;/span&gt; ldapi:/// &lt;span class="nt"&gt;-f&lt;/span&gt; /etc/openldap/schema/cosine.ldif
&lt;span class="nb"&gt;sudo &lt;/span&gt;ldapadd &lt;span class="nt"&gt;-Y&lt;/span&gt; EXTERNAL &lt;span class="nt"&gt;-H&lt;/span&gt; ldapi:/// &lt;span class="nt"&gt;-f&lt;/span&gt; /etc/openldap/schema/nis.ldif
&lt;span class="nb"&gt;sudo &lt;/span&gt;ldapadd &lt;span class="nt"&gt;-Y&lt;/span&gt; EXTERNAL &lt;span class="nt"&gt;-H&lt;/span&gt; ldapi:/// &lt;span class="nt"&gt;-f&lt;/span&gt; /etc/openldap/schema/inetorgperson.ldif
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  OpenLDAP Verification
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Create objects, Organizational Unit and group
&lt;/h3&gt;

&lt;p&gt;Create a file, &lt;strong&gt;entries.ldif&lt;/strong&gt;, and add below content which &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;create a user, joe&lt;/li&gt;
&lt;li&gt;assign joe to 2 groups, joe &amp;amp; Engineering
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dn: dc=abc,dc=local
dc: abc
objectClass: top
objectClass: domain

dn: ou=People,dc=abc,dc=local
objectClass: organizationalUnit
ou: People

dn: ou=Groups,dc=abc,dc=local
objectClass: organizationalUnit
ou: Groups

dn: cn=Engineering,ou=Groups,dc=abc,dc=local
cn: Engineering
objectClass: posixGroup
gidNumber: 20100
memberUid: joe

dn: uid=joe,ou=People,dc=abc,dc=local
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
uid: joe
sn: Ho
givenName: Joe
cn: Joe Ho
displayName: Joe Ho
uidNumber: 20001
gidNumber: 20001
loginShell: /bin/bash
homeDirectory: /home/joe
shadowMin: 0
shadowMax: 2
shadowWarning: 1
userPassword: {CRYPT}x
shadowLastChange: 19261
dn: cn=joe,ou=Groups,dc=abc,dc=local
cn: joe
objectClass: posixGroup
gidNumber: 20001
memberUid: joe
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apply the content&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ldapadd &lt;span class="nt"&gt;-x&lt;/span&gt; &lt;span class="nt"&gt;-W&lt;/span&gt; &lt;span class="nt"&gt;-D&lt;/span&gt; &lt;span class="s2"&gt;"cn=admin,dc=abc,dc=local"&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; entries.ldif
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Test querying LDAP
&lt;/h3&gt;

&lt;p&gt;Query all entries&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ldapsearch -D cn="admin,dc=abc,dc=local" -W -b "dc=abc,dc=local"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&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%2Fuploads%2Farticles%2Fv47w4m6gw9yv0xpze4h6.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%2Fuploads%2Farticles%2Fv47w4m6gw9yv0xpze4h6.png" alt="Query result"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;We complete the whole set up and are able to create users and manage them in LDAP&lt;/p&gt;

&lt;p&gt;Original Post: &lt;a href="https://joeho.xyz/blog-posts/install-and-configure-openldap-server-in-centos7/" rel="noopener noreferrer"&gt;Install and configure OpenLDAP server in CentOS 7 | Joe Ho Blog&lt;/a&gt;&lt;/p&gt;

</description>
      <category>linux</category>
      <category>devops</category>
      <category>centos</category>
      <category>ldap</category>
    </item>
    <item>
      <title>How to store secrets in Azure Databricks</title>
      <dc:creator>JoeHo</dc:creator>
      <pubDate>Tue, 27 Sep 2022 01:18:31 +0000</pubDate>
      <link>https://forem.com/joeho888/how-to-store-secrets-in-azure-databricks-28g7</link>
      <guid>https://forem.com/joeho888/how-to-store-secrets-in-azure-databricks-28g7</guid>
      <description>&lt;h2&gt;
  
  
  Background
&lt;/h2&gt;

&lt;p&gt;In Azure Databricks, we can write code to perform data transformation on data stored in various Azure Services, e.g. Azure Blob Storage, Azure Synapse. However, as other programs, sometimes, you want to protect credentials used in Azure Databricks, Azure Databricks provides a solid secret management approach to help you achieve that.&lt;/p&gt;

&lt;h2&gt;
  
  
  Steps
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Prepare Databricks command-line interface (CLI) in Azure Cloud Shell
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Configure your cloud shell environment
&lt;/h4&gt;

&lt;p&gt;Open Cloud Shell &amp;amp; make sure you select “Bash” for the Cloud Shell Environment.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--c0GaCFvU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oncwddz9dnu67zdp25q3.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--c0GaCFvU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oncwddz9dnu67zdp25q3.jpg" alt="Launch bash cloud shell" width="498" height="267"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Set up Virtual Environment
&lt;/h4&gt;

&lt;p&gt;Create Virtual Environment with below command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Bash&lt;/span&gt;
virtualenv &lt;span class="nt"&gt;-p&lt;/span&gt; /usr/bin/python2.7 databrickscli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yNp7Nt39--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hu07fhe1shhob0m7vgmp.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yNp7Nt39--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hu07fhe1shhob0m7vgmp.jpg" alt="Create virtual environment" width="800" height="341"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Activate your virtual environment
&lt;/h4&gt;

&lt;p&gt;Activate your virtual environment with below command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Bash&lt;/span&gt;
&lt;span class="nb"&gt;source &lt;/span&gt;databrickscli/bin/activate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Y403ITo5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/09ug5xi6uibh2gscxvbc.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Y403ITo5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/09ug5xi6uibh2gscxvbc.jpg" alt="Activate virtual environment" width="800" height="358"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Install Databricks CLI
&lt;/h4&gt;

&lt;p&gt;Install Databricks CLI with below command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Bash&lt;/span&gt;
pip &lt;span class="nb"&gt;install &lt;/span&gt;databricks-cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uFdJFGiC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/00uc56wsykq6e0cbkb0m.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uFdJFGiC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/00uc56wsykq6e0cbkb0m.jpg" alt="Install Databricks CLI" width="800" height="402"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Create secret in Azure Databricks
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Set up authentication
&lt;/h4&gt;

&lt;p&gt;Before you can create a secret, you need to authenticate as a user of the Azure Databricks, which requires your Azure Databrics workspace’s URL and a token&lt;/p&gt;

&lt;h5&gt;
  
  
  Get your Azure Databricks workspace’s URL
&lt;/h5&gt;

&lt;p&gt;You can navigate to your Azure Databricks workspace and copy its URL.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8SDC_wP5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kve809wme6dgtq2mwiuf.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8SDC_wP5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kve809wme6dgtq2mwiuf.jpg" alt="Get Databricks URL" width="800" height="234"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h5&gt;
  
  
  Generate Access Token for your Azure Databricks workspace
&lt;/h5&gt;

&lt;p&gt;You can follow below steps to retrieve access token&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Launch Databricks workspace
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5Om74TF3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m1ytt0y9k3dr0g0iuawf.jpg" alt="Launch Databricks Workspace" width="800" height="340"&gt;
&lt;/li&gt;
&lt;li&gt;Click 'User Settings'
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dtNINPdz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5do8aha7z1bj7fxcb8c3.jpg" alt="Click 'User Settings'" width="800" height="245"&gt;
&lt;/li&gt;
&lt;li&gt;Click 'Generate New Token'
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ObOTayj2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kautbynrv2tpsbpabrm1.jpg" alt="Generate access token" width="800" height="209"&gt;
&lt;/li&gt;
&lt;li&gt;Configure access token &amp;amp; click 'Generate'
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--snViJfZ0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gan07dwuq1l1pu8ebope.jpg" alt="Configure access token" width="513" height="250"&gt;
&lt;/li&gt;
&lt;li&gt;Copy access token
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_kCHmfU0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7w83zooacj4pzt1lny3n.jpg" alt="Copy access token" width="520" height="227"&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Create Secret Scope
&lt;/h4&gt;

&lt;p&gt;After authentication, you need to first create a secret scope which you may group several secrets. &lt;/p&gt;

&lt;p&gt;If your databricks is in Standard plan, you can only create secret scope which will be shared with other users in the same workspace.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ASsoqIE9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gzqg3736si1suzazctwx.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ASsoqIE9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gzqg3736si1suzazctwx.jpg" alt="Check databricks plan" width="800" height="208"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Bash&lt;/span&gt;
databricks secrets create-scope &lt;span class="nt"&gt;--scope&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;scope&lt;/span&gt;&lt;span class="sh"&gt;&amp;gt;&amp;gt;

# Example
databricks secrets create-scope --scope storage --initial-manage-principal users # Standard Plan
databricks secrets create-scope --scope storage # Premium plan
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--J2uKXKvW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3jfp5asp2gax2wiiixmb.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--J2uKXKvW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3jfp5asp2gax2wiiixmb.jpg" alt="Create secret scope" width="800" height="55"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Create Secret
&lt;/h4&gt;

&lt;p&gt;You can use below command to create secret under the specified scope.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Bash&lt;/span&gt;
databricks secrets put &lt;span class="nt"&gt;--scope&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;scope&lt;/span&gt;&lt;span class="sh"&gt;&amp;gt;&amp;gt; --key &amp;lt;&amp;lt;key name&amp;gt;&amp;gt;

databricks secrets put --scope storage --key blob #Example
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--929N-umF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ebyf7d6kb6vtptgjgemg.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--929N-umF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ebyf7d6kb6vtptgjgemg.jpg" alt="Type command to launch secret editor" width="800" height="108"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CXnpx1Rm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zw9a9i05haf3727lugnd.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CXnpx1Rm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zw9a9i05haf3727lugnd.jpg" alt="Type your secret and save" width="800" height="279"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Use Secret in Notebook
&lt;/h4&gt;

&lt;p&gt;You can use secret by below command in notebook.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Python
&lt;/span&gt;&lt;span class="n"&gt;dbutils&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;secrets&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;scope&lt;/span&gt;&lt;span class="o"&gt;=&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;scope&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;dbutils&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;secrets&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;scope&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;blob&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;#Example
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wTQXTkHK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s8590ycthanyhng0nbr8.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wTQXTkHK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s8590ycthanyhng0nbr8.jpg" alt="Use stored secret in notebook" width="800" height="334"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Original Post: &lt;a href="https://joeho.xyz/blog-posts/how-to-store-secrets-in-azure-databricks/"&gt;https://joeho.xyz/blog-posts/how-to-store-secrets-in-azure-databricks/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>azure</category>
      <category>database</category>
      <category>datascience</category>
      <category>cloud</category>
    </item>
    <item>
      <title>How to connect to Azure Synapse in Azure Databricks</title>
      <dc:creator>JoeHo</dc:creator>
      <pubDate>Tue, 27 Sep 2022 00:53:53 +0000</pubDate>
      <link>https://forem.com/joeho888/how-to-connect-to-azure-synapse-in-azure-databricks-335k</link>
      <guid>https://forem.com/joeho888/how-to-connect-to-azure-synapse-in-azure-databricks-335k</guid>
      <description>&lt;h2&gt;
  
  
  Background
&lt;/h2&gt;

&lt;p&gt;With Azure Databricks, we can easily transform huge size of data in parallel and store the transformed data in different Azure services, one of them is Azure Synapse (formerly SQL DW). Azure Databricks has built-in connector which lets us read and write data easily from Azure Synapse.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisite
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Azure Databricks Workspace&lt;/li&gt;
&lt;li&gt;Azure Blob Storage or Azure Data Lake Gen 2&lt;/li&gt;
&lt;li&gt;Azure Synapse Instance&lt;/li&gt;
&lt;li&gt;Azure Synapse User Credentials&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Steps
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Configure storage key in notebook session
&lt;/h3&gt;

&lt;p&gt;This will configure your storage credentials in your notebook session, which we will use them to connect to that storage. This storage acts as a staging storage when you read and write data from Azure Synapse. Currently, only Azure Blob Storage and Azure Data Lake Gen 2 are supported, they have slightly different configurations. Below are session configuration for both types of storage.&lt;/p&gt;

&lt;h4&gt;
  
  
  Azure Blob Storage As Staging Storage
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Python
&lt;/span&gt;
&lt;span class="n"&gt;spark&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;conf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;azure&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;your&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;storage&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;blob&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;core&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;windows&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;net&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;”&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;your&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;storage&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;access&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Azure Data Lake Gen 2 As Staging Storage
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Python
&lt;/span&gt;
&lt;span class="n"&gt;spark&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;conf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;azure&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;your&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;storage&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="n"&gt;dfs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;core&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;windows&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;net&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;”&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;your&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;storage&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;access&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aV9HOcwb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6aemlqmwxdc0ww5ciww0.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aV9HOcwb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6aemlqmwxdc0ww5ciww0.jpg" alt="Configure storage key in notebook session" width="602" height="182"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Configure Azure Synapse connection
&lt;/h3&gt;

&lt;p&gt;Next, we will define below variables&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Azure Synapse connection string&lt;/li&gt;
&lt;li&gt;Staging storage folder (i.e. where some temporary data will be written to when you read/write data from/to Azure Synapse)&lt;/li&gt;
&lt;li&gt;An Azure Synapse Table which you will read/write data from/to Azure Synapse
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Python
&lt;/span&gt;
&lt;span class="c1"&gt;# Azure Synapse Connection Configuration
&lt;/span&gt;&lt;span class="n"&gt;dwDatabase&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;your&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;database&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;
&lt;span class="n"&gt;dwServer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;your&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;sever&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;
&lt;span class="n"&gt;dwUser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;your&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;database&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;
&lt;span class="n"&gt;dwPass&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;your&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;database&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;
&lt;span class="n"&gt;dwJdbcPort&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="s"&gt;"1433"&lt;/span&gt;
&lt;span class="n"&gt;dwJdbcExtraOptions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"encrypt=true;trustServerCertificate=true;hostNameInCertificate=*.database.windows.net;loginTimeout=30;"&lt;/span&gt;
&lt;span class="n"&gt;sqlDwUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s"&gt;"jdbc:sqlserver://&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;dwServer&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;:&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;dwJdbcPort&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;;database=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;dwDatabase&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;;user=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;dwUser&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;;password=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;dwPass&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;;$&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;dwJdbcExtraOptions&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;

&lt;span class="c1"&gt;# Staging Storage Configuration
# Azure Blob Storage
# tempDir = "wasbs://&amp;lt;&amp;lt;container&amp;gt;&amp;gt;@&amp;lt;&amp;lt;your-storage-account-name&amp;gt;&amp;gt;.blob.core.windows.net/&amp;lt;&amp;lt;folder-for-temporary-data&amp;gt;&amp;gt;"
&lt;/span&gt;
&lt;span class="c1"&gt;# Azure Data Lake Gen 2
&lt;/span&gt;&lt;span class="n"&gt;tempDir&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"abfss://&amp;lt;&amp;lt;container &amp;gt;&amp;gt;@&amp;lt;&amp;lt;your-storage-account-name&amp;gt;&amp;gt;.dfs.core.windows.net/&amp;lt;&amp;lt;folder-for-temporary-data&amp;gt;&amp;gt;"&lt;/span&gt;

&lt;span class="c1"&gt;# Azure Synapse Table
&lt;/span&gt;&lt;span class="n"&gt;tableName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;your&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;azure&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;synapse&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ow"&gt;or&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LXttEsT_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fjote1o52qzqmj08l7oe.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LXttEsT_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fjote1o52qzqmj08l7oe.jpg" alt="Configure Azure Synapse connection" width="800" height="347"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Read Data from Azure Synapse
&lt;/h3&gt;

&lt;p&gt;Then, we will try to read data from Azure Synapse&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Python
&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;spark&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt; \
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"com.databricks.spark.sqldw"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; \
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;option&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sqlDwUrl&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; \
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;option&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"tempDir"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tempDir&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; \
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;option&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"forwardSparkAzureStorageCredentials"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"true"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; \
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;option&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"dbTable"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tableName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; \
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;load&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--n445yklJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/76kwpfh7xgeqw165n2m1.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--n445yklJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/76kwpfh7xgeqw165n2m1.jpg" alt="Read data from Azure Synapse" width="602" height="362"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Write Data to Azure Synapse
&lt;/h3&gt;

&lt;p&gt;Finally, we will try to write data to Azure Synapse&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Python
&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt; \
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'append'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; \ &lt;span class="c1"&gt;# Append Data
&lt;/span&gt;  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"com.databricks.spark.sqldw"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; \
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;option&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sqlDwUrl&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; \
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;option&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"tempDir"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tempDir&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; \
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;option&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"forwardSparkAzureStorageCredentials"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"true"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; \
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;option&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"dbTable"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tableName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; \
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;save&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--j0KK-ZTf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/35yk3buqf4gllur6ybto.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--j0KK-ZTf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/35yk3buqf4gllur6ybto.jpg" alt="Write data to Azure Synapse" width="602" height="424"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Bonus: Why do we need staging storage
&lt;/h3&gt;

&lt;p&gt;As mentioned above, staging folder is needed to store some temporary data whenever we read/write data from/to Azure Synapse. Whenever we read/write data, we actually leverage &lt;a href="https://docs.microsoft.com/en-us/sql/relational-databases/polybase/polybase-guide?view=sql-server-ver15"&gt;PolyBase&lt;/a&gt; to move the data, which staging storage is used to achieve high performance.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--j0Tp5QxT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ikkb6nuytoobpdk2ojol.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--j0Tp5QxT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ikkb6nuytoobpdk2ojol.jpg" alt="Data in temporary storage" width="602" height="328"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Another Bonus: Secret Management in Azure Databricks
&lt;/h3&gt;

&lt;p&gt;The code above put our secrets, e.g. user credentials, storage key in pain text. Actually, we should hide them in the notebooks. You can refer to this &lt;a href="https://dev.to/joeho888/how-to-store-secrets-in-azure-databricks-28g7"&gt;guide&lt;/a&gt; for more detail.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--87PMT7PG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9hg7kfd9417k90zcpu98.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--87PMT7PG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9hg7kfd9417k90zcpu98.jpg" alt="Retrieve storage key from databricks secret" width="602" height="115"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Original Post: &lt;a href="https://joeho.xyz/blog-posts/how-to-connect-to-azure-synapse-in-azure-databricks/"&gt;https://joeho.xyz/blog-posts/how-to-connect-to-azure-synapse-in-azure-databricks/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>azure</category>
      <category>datascience</category>
      <category>database</category>
      <category>cloud</category>
    </item>
  </channel>
</rss>
