How to add google_tag script to header with custom environment variables? I'm trying to add Google Tag Manager to the &lt;head&gt; of my document.

Unfortunately, the way I'm doing it with an HTML tag render element, the ampersands (&amp;) are being escaped.   

function mymodule_page_attachments(array &amp;$page) {
  $config = \Drupal::config('mymodule.config');
  $gtm_id = $config-&gt;get('google_tag_manager_id');
  $gtm_auth = $config-&gt;get('gtm_auth');
  $gtm_preview = $config-&gt;get('gtm_preview');

  /** @var \Drupal\mymodule\AnalyticsUtility $utility */
  $utility = \Drupal::service('mymodule.utility');

  if (!empty($gtm_id) &amp;&amp; !empty($gtm_auth) &amp;&amp; !empty($gtm_preview) &amp;&amp; $utility-&gt;isAdminPage() === FALSE) {


    $script = "(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&amp;l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl+ '&amp;gtm_auth={$gtm_auth}&amp;gtm_preview={$gtm_preview}&amp;gtm_cookies_win=x';f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','{$gtm_id}');\n";


    $page['#attached']['html_head'][] = [
      ['#tag' =&gt; 'script', '#value' =&gt; $script],
      'google_tag_manager',
    ];
  }
}


This results in ampersands in the code.

&lt;script&gt;(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&amp;amp;l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl+ '&amp;amp;gtm_auth=testrWktRcmjpViiQKW&amp;amp;gtm_preview=env-6&amp;amp;gtm_cookies_win=x';f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-K53TEST');&lt;/script&gt;


There are two modules with Google Tag Manager and they both add the code using hook_page_attachments().

The recommendation for adding JavaScript is to use an external file; yet, the Google Tag Manager documentation recommends adding the script in &lt;head&gt;.

Is there a way to do this with Drupal settings and a javascript file in my custom module? Alternatively, is there a way not to convert the ampersands to HTML entities?
The recommendation for adding javascript is to use an external file


That is not always the case and it is more of a guideline than a hard rule. 

There is a way to do what you ask, but you shouldn't because the google_tag module does exactly what you to want to do. It also allows you to include the GTM snippet inline or as a file.