From fd02ecd290fe6b7acd3831d6aff1a349372b2887 Mon Sep 17 00:00:00 2001 From: Dag Wieers Date: Thu, 15 Nov 2018 22:17:29 +0100 Subject: [PATCH] Code example improvements in Windows documentation (#45055) This PR includes: - Using explicit yaml+jinja code-blocks - Work around pygments lexer issues with colons (in URLs and options) --- docs/docsite/rst/user_guide/windows_dsc.rst | 95 +++++++----- docs/docsite/rst/user_guide/windows_faq.rst | 2 +- docs/docsite/rst/user_guide/windows_setup.rst | 53 ++++--- docs/docsite/rst/user_guide/windows_usage.rst | 142 ++++++++++-------- docs/docsite/rst/user_guide/windows_winrm.rst | 81 ++++++---- 5 files changed, 224 insertions(+), 149 deletions(-) diff --git a/docs/docsite/rst/user_guide/windows_dsc.rst b/docs/docsite/rst/user_guide/windows_dsc.rst index e9ad9c85a98..87816bc2d6d 100644 --- a/docs/docsite/rst/user_guide/windows_dsc.rst +++ b/docs/docsite/rst/user_guide/windows_dsc.rst @@ -62,7 +62,9 @@ according to the resource it is managing. A list of built in resources can be found at `resources `_. Using the `Registry `_ -resource as an example, this is the DSC definition as documented by Microsoft:: +resource as an example, this is the DSC definition as documented by Microsoft: + +.. code-block:: powershell Registry [string] #ResourceName { @@ -85,9 +87,11 @@ options are parameters that are used to define the resource, such as ``Key`` and keeping the case as-is is recommended becuase it makes it easier to distinguish DSC resource options from Ansible's ``win_dsc`` options. -This is what the Ansible task version of the above DSC Registry resource would look like:: +This is what the Ansible task version of the above DSC Registry resource would look like: + +.. code-block:: yaml+jinja - - name: use win_dsc module with the Registry DSC resource + - name: Use win_dsc module with the Registry DSC resource win_dsc: resource_name: Registry Ensure: Present @@ -109,15 +113,17 @@ A ``[PSCredential]`` object is used to store credentials in a secure way, but Ansible has no way to serialize this over JSON. To set a DSC PSCredential property, the definition of that parameter should have two entries that are suffixed with ``_username`` and ``_password`` for the username and password respectively. -For example:: +For example: - PsDscRunAsCredential_username: '{{ansible_user}}' - PsDscRunAsCredential_password: '{{ansible_password}}' +.. code-block:: yaml+jinja + + PsDscRunAsCredential_username: '{{ ansible_user }}' + PsDscRunAsCredential_password: '{{ ansible_password }}' SourceCredential_username: AdminUser SourceCredential_password: PasswordForAdminUser -.. Note:: You should set ``no_log: true`` on the task definition in +.. Note:: You should set ``no_log: yes`` on the task definition in Ansible to ensure any credentials used are not stored in any log file or console output. @@ -126,7 +132,9 @@ CimInstance Type A ``[CimInstance]`` object is used by DSC to store a dictionary object based on a custom class defined by that resource. Defining a value that takes in a ``[CimInstance]`` in YAML is the same as defining a dictionary in YAML. -For example, to define a ``[CimInstance]`` value in Ansible:: +For example, to define a ``[CimInstance]`` value in Ansible: + +.. code-block:: yaml+jinja # [CimInstance]AuthenticationInfo == MSFT_xWebAuthenticationInformation AuthenticationInfo: @@ -149,7 +157,9 @@ Simple type arrays like ``[string[]]`` or ``[UInt32[]]`` are defined as a list or as a comma separated string which are then cast to their type. Using a list is recommended because the values are not manually parsed by the ``win_dsc`` module before being passed to the DSC engine. For example, to define a simple -type array in Ansible:: +type array in Ansible: + +.. code-block:: yaml+jinja # [string[]] ValueData: entry1, entry2, entry3 @@ -165,7 +175,9 @@ type array in Ansible:: - 3010 Complex type arrays like ``[CimInstance[]]`` (array of dicts), can be defined -like this example:: +like this example: + +.. code-block:: yaml+jinja # [CimInstance[]]BindingInfo == MSFT_xWebBindingInformation BindingInfo: @@ -196,18 +208,20 @@ force the DSC engine to run under a different account. As ``_username`` and ``_password`` suffix. Using the Registry resource type as an example, this is how to define a task -to access the ``HKEY_CURRENT_USER`` hive of the Ansible user:: +to access the ``HKEY_CURRENT_USER`` hive of the Ansible user: + +.. code-block:: yaml+jinja - - name: use win_dsc with PsDscRunAsCredential to run as a different user + - name: Use win_dsc with PsDscRunAsCredential to run as a different user win_dsc: resource_name: Registry Ensure: Present Key: HKEY_CURRENT_USER\ExampleKey ValueName: TestValue ValueData: TestData - PsDscRunAsCredential_username: '{{ansible_user}}' - PsDscRunAsCredential_password: '{{ansible_password}}' - no_log: true + PsDscRunAsCredential_username: '{{ ansible_user }}' + PsDscRunAsCredential_password: '{{ ansible_password }}' + no_log: yes Custom DSC Resources ```````````````````` @@ -223,10 +237,10 @@ The ``Find-DscResource`` cmdlet can also be used to find custom resources. For e .. code-block:: powershell - # find all DSC resources in the configured repositories + # Find all DSC resources in the configured repositories Find-DscResource - # find all DSC resources that relate to SQL + # Find all DSC resources that relate to SQL Find-DscResource -ModuleName "*sql*" .. Note:: DSC resources developed by Microsoft that start with ``x``, means the @@ -241,9 +255,11 @@ There are three ways that a DSC resource can be installed on a host: * Saving the module manually and copying it another host This is an example of installing the ``xWebAdministration`` resources using -``win_psmodule``:: +``win_psmodule``: - - name: install xWebAdministration DSC resource +.. code-block:: yaml+jinja + + - name: Install xWebAdministration DSC resource win_psmodule: name: xWebAdministration state: present @@ -255,7 +271,10 @@ The first two methods above only work when the host has access to the internet. When a host does not have internet access, the module must first be installed using the methods above on another host with internet access and then copied across. To save a module to a local filepath, the following PowerShell cmdlet -can be run:: +can be run: + +.. comment: Pygments powershell lexer does not support colons (i.e. URLs) +.. code-block:: guess Save-Module -Name xWebAdministration -Path C:\temp @@ -271,21 +290,21 @@ Examples Extract a zip file ------------------ -.. code-block:: yaml +.. code-block:: yaml+jinja - - name: extract a zip file + - name: Extract a zip file win_dsc: resource_name: Archive - Destination: c:\temp\output + Destination: C:\temp\output Path: C:\temp\zip.zip Ensure: Present Create a directory ------------------ -.. code-block:: yaml +.. code-block:: yaml+jinja - - name: create file with some text + - name: Create file with some text win_dsc: resource_name: File DestinationPath: C:\temp\file @@ -295,7 +314,7 @@ Create a directory Ensure: Present Type: File - - name: create directory that is hidden is set with the System attribute + - name: Create directory that is hidden is set with the System attribute win_dsc: resource_name: File DestinationPath: C:\temp\hidden-directory @@ -306,14 +325,14 @@ Create a directory Interact with Azure ------------------- -.. code-block:: yaml +.. code-block:: yaml+jinja - - name: install xAzure DSC resources + - name: Install xAzure DSC resources win_psmodule: name: xAzure state: present - - name: create virtual machine in Azure + - name: Create virtual machine in Azure win_dsc: resource_name: xAzureVM ImageName: a699494373c04fc0bc8f2bb1389d6106__Windows-Server-2012-R2-201409.01-en.us-127GB.vhd @@ -321,31 +340,31 @@ Interact with Azure ServiceName: ServiceName StorageAccountName: StorageAccountName InstanceSize: Medium - Windows: True + Windows: yes Ensure: Present - Credential_username: '{{ansible_user}}' - Credential_password: '{{ansible_password}}' + Credential_username: '{{ ansible_user }}' + Credential_password: '{{ ansible_password }}' Setup IIS Website ----------------- -.. code-block:: yaml +.. code-block:: yaml+jinja - - name: install xWebAdministration module + - name: Install xWebAdministration module win_psmodule: name: xWebAdministration state: present - - name: install IIS features that are required + - name: Install IIS features that are required win_dsc: resource_name: WindowsFeature - Name: '{{item}}' + Name: '{{ item }}' Ensure: Present loop: - Web-Server - Web-Asp-Net45 - - name: setup web content + - name: Setup web content win_dsc: resource_name: File DestinationPath: C:\inetpub\IISSite\index.html @@ -357,7 +376,7 @@ Setup IIS Website Ensure: present - - name: create new website + - name: Create new website win_dsc: resource_name: xWebsite Name: NewIISSite diff --git a/docs/docsite/rst/user_guide/windows_faq.rst b/docs/docsite/rst/user_guide/windows_faq.rst index c4f7fa328da..bf52a5b2865 100644 --- a/docs/docsite/rst/user_guide/windows_faq.rst +++ b/docs/docsite/rst/user_guide/windows_faq.rst @@ -57,7 +57,7 @@ installed version and then clone the git repo. git clone https://github.com/ansible/ansible.git source ansible/hacking/env-setup - # to enable Ansible on login, run the following + # To enable Ansible on login, run the following echo ". ~/ansible/hacking/env-setup -q' >> ~/.bashrc Can I use SSH keys to authenticate? diff --git a/docs/docsite/rst/user_guide/windows_setup.rst b/docs/docsite/rst/user_guide/windows_setup.rst index 089eff371cf..9c04741d745 100644 --- a/docs/docsite/rst/user_guide/windows_setup.rst +++ b/docs/docsite/rst/user_guide/windows_setup.rst @@ -33,7 +33,7 @@ requirement. You can use the `Upgrade-PowerShell.ps1 `_ package to communicate with Windows servers over WinRM. It is not installed by default -with the Ansible package, but can be installed by running the following:: +with the Ansible package, but can be installed by running the following: + +.. code-block:: shell pip install "pywinrm>=0.3.0" @@ -52,7 +54,9 @@ also the most insecure. This is because the username and password are simply base64 encoded, and if a secure channel is not in use (eg, HTTPS) then it can be decoded by anyone. Basic authentication can only be used for local accounts (not domain accounts). -The following example shows host vars configured for basic authentication:: +The following example shows host vars configured for basic authentication: + +.. code-block:: yaml+jinja ansible_user: LocalUsername ansible_password: Password @@ -62,6 +66,7 @@ The following example shows host vars configured for basic authentication:: Basic authentication is not enabled by default on a Windows host but can be enabled by running the following in PowerShell: +.. comment: Pygments powershell lexer does not support colons (i.e. URLs) .. code-block:: guess Set-Item -Path WSMan:\localhost\Service\Auth\Basic -Value $true @@ -71,7 +76,9 @@ Certificate Certificate authentication uses certificates as keys similar to SSH key pairs, but the file format and key generation process is different. -The following example shows host vars configured for certificate authentication:: +The following example shows host vars configured for certificate authentication: + +.. code-block:: yaml+jinja ansible_connection: winrm ansible_winrm_cert_pem: /path/to/certificate/public/key.pem @@ -81,6 +88,7 @@ The following example shows host vars configured for certificate authentication: Certificate authentication is not enabled by default on a Windows host but can be enabled by running the following in PowerShell: +.. comment: Pygments powershell lexer does not support colons (i.e. URLs) .. code-block:: guess Set-Item -Path WSMan:\localhost\Service\Auth\Certificate -Value $true @@ -111,7 +119,7 @@ To generate a certificate with ``OpenSSL``: .. code-block:: shell - # set the name of the local user that will have the key mapped to + # Set the name of the local user that will have the key mapped to USERNAME="username" cat > openssl.conf << EOL @@ -129,13 +137,13 @@ To generate a certificate with ``OpenSSL``: To generate a certificate with ``New-SelfSignedCertificate``: -.. code-block:: guess +.. code-block:: powershell - # set the name of the local user that will have the key mapped + # Set the name of the local user that will have the key mapped $username = "username" $output_path = "C:\temp" - # instead of generating a file, the cert will be added to the personal + # Instead of generating a file, the cert will be added to the personal # LocalComputer folder in the certificate store $cert = New-SelfSignedCertificate -Type Custom ` -Subject "CN=$username" ` @@ -144,14 +152,14 @@ To generate a certificate with ``New-SelfSignedCertificate``: -KeyAlgorithm RSA ` -KeyLength 2048 - # export the public key + # Export the public key $pem_output = @() $pem_output += "-----BEGIN CERTIFICATE-----" $pem_output += [System.Convert]::ToBase64String($cert.RawData) -replace ".{64}", "$&`n" $pem_output += "-----END CERTIFICATE-----" [System.IO.File]::WriteAllLines("$output_path\cert.pem", $pem_output) - # export the private key in a PFX file + # Export the private key in a PFX file [System.IO.File]::WriteAllBytes("$output_path\cert.pfx", $cert.Export("Pfx")) @@ -169,7 +177,7 @@ both the issuing certificate and public key are the same. Following example shows how to import the issuing certificate: -.. code-block:: guess +.. code-block:: powershell $cert = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Certificate2 $cert.Import("cert.pem") @@ -187,7 +195,7 @@ Following example shows how to import the issuing certificate: The code to import the client certificate public key is: -.. code-block:: guess +.. code-block:: powershell $cert = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Certificate2 $cert.Import("cert.pem") @@ -206,13 +214,14 @@ Once the certificate has been imported, it needs to be mapped to the local user This can be done with the following PowerShell command: +.. comment: Pygments powershell lexer does not support colons (i.e. URLs) .. code-block:: guess $username = "username" $password = ConvertTo-SecureString -String "password" -AsPlainText -Force $credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $username, $password - # this is the issuer thumbprint which in the case of a self generated cert + # This is the issuer thumbprint which in the case of a self generated cert # is the public key thumbprint, additional logic may be required for other # scenarios $thumbprint = (Get-ChildItem -Path cert:\LocalMachine\root | Where-Object { $_.Subject -eq "CN=$username" }).Thumbprint @@ -247,7 +256,9 @@ Kerberos has several advantages over using NTLM: the authentication stage. * Unlike Kerberos, NTLM does not allow credential delegation. -This example shows host variables configured to use NTLM authentication:: +This example shows host variables configured to use NTLM authentication: + +.. code-block:: yaml+jinja ansible_user: LocalUsername ansible_password: Password @@ -264,7 +275,9 @@ is available through WinRM. Kerberos requires some additional setup work on the Ansible host before it can be used properly. -The following example shows host vars configured for Kerberos authentication:: +The following example shows host vars configured for Kerberos authentication: + +.. code-block:: yaml+jinja ansible_user: username@MY.DOMAIN.COM ansible_password: Password @@ -328,7 +341,7 @@ that it can communicate with a domain. This configuration is done through the To configure Kerberos, in the section that starts with: -:: +.. code-block:: ini [realms] @@ -336,7 +349,7 @@ Add the full domain name and the fully qualified domain names of the primary and secondary Active Directory domain controllers. It should look something like this: -:: +.. code-block:: ini [realms] MY.DOMAIN.COM = { @@ -346,13 +359,13 @@ like this: In the section that starts with: -:: +.. code-block:: ini [domain_realm] Add a line like the following for each domain that Ansible needs access for: -:: +.. code-block:: ini [domain_realm] .my.domain.com = MY.DOMAIN.COM @@ -443,7 +456,9 @@ not compromised and are trusted. CredSSP can be used for both local and domain accounts and also supports message encryption over HTTP. -To use CredSSP authentication, the host vars are configured like so:: +To use CredSSP authentication, the host vars are configured like so: + +.. code-block:: yaml+jinja ansible_user: Username ansible_password: Password @@ -457,7 +472,7 @@ There are some extra host variables that can be set as shown below:: CredSSP authentication is not enabled by default on a Windows host, but can be enabled by running the following in PowerShell: -.. code-block:: guess +.. code-block:: powershell Enable-WSManCredSSP -Role Server -Force @@ -492,7 +507,7 @@ needs to be installed. Once the update has been applied and the Windows host rebooted, run the following PowerShell commands to enable TLS 1.2: -.. code-block:: guess +.. code-block:: powershell $reg_path = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2" New-Item -Path $reg_path @@ -515,13 +530,14 @@ another certificate. To explicitly set the certificate to use for CredSSP: +.. comment: Pygments powershell lexer does not support colons (i.e. URLs) .. code-block:: guess - # note the value $certificate_thumbprint will be different in each + # Note the value $certificate_thumbprint will be different in each # situation, this needs to be set based on the cert that is used. $certificate_thumbprint = "7C8DCBD5427AFEE6560F4AF524E325915F51172C" - # set the thumbprint value + # Set the thumbprint value Set-Item -Path WSMan:\localhost\Service\CertificateThumbprint -Value $certificate_thumbprint Non-Administrator Accounts @@ -529,7 +545,7 @@ Non-Administrator Accounts WinRM is configured by default to only allow connections from accounts in the local ``Administrators`` group. This can be changed by running: -.. code-block:: guess +.. code-block:: powershell winrm configSDDL default @@ -565,6 +581,7 @@ should only be used for development and debugging purposes, as anything sent from Ansible can viewed by anyone on the network. To disable the encryption requirement, run the following from PowerShell on the target host: +.. comment: Pygments powershell lexer does not support colons (i.e. URLs) .. code-block:: guess Set-Item -Path WSMan:\localhost\Service\AllowUnencrypted -Value $true @@ -580,16 +597,18 @@ username, password, and connection type of the remote hosts. These variables are most easily set up in the inventory, but can be set on the ``host_vars``/ ``group_vars`` level. -When setting up the inventory, the following variables are required:: +When setting up the inventory, the following variables are required: + +.. code-block:: yaml+jinja - # it is suggested that these be encrypted with ansible-vault: + # It is suggested that these be encrypted with ansible-vault: # ansible-vault edit group_vars/windows.yml ansible_connection: winrm - # may also be passed on the command-line via --user + # May also be passed on the command-line via --user ansible_user: Administrator - # may also be supplied at runtime with --ask-pass + # May also be supplied at runtime with --ask-pass ansible_password: SecretPasswordGoesHere @@ -649,7 +668,7 @@ for additional configuration of WinRM connections: * ``ansible_winrm_send_cbt``: When using ``ntlm`` or ``kerberos`` over HTTPS, the authentication library will try to send channel binding tokens to mitigate against man in the middle attacks. This flag controls whether these - bindings will be sent or not (default: ``True``). + bindings will be sent or not (default: ``yes``). * ``ansible_winrm_*``: Any additional keyword arguments supported by ``winrm.Protocol`` may be provided in place of ``*`` @@ -676,7 +695,9 @@ using the `ipaddress `_ package and pass to pywinrm correctly. When defining a host using an IPv6 address, just add the IPv6 address as you -would an IPv4 address or hostname:: +would an IPv4 address or hostname: + +.. code-block:: ini [windows-server] 2001:db8::1