summaryrefslogtreecommitdiffstats
path: root/docs/docsite/rst/os_guide/windows_dsc.rst
diff options
context:
space:
mode:
Diffstat (limited to 'docs/docsite/rst/os_guide/windows_dsc.rst')
-rw-r--r--docs/docsite/rst/os_guide/windows_dsc.rst508
1 files changed, 508 insertions, 0 deletions
diff --git a/docs/docsite/rst/os_guide/windows_dsc.rst b/docs/docsite/rst/os_guide/windows_dsc.rst
new file mode 100644
index 0000000..1588a23
--- /dev/null
+++ b/docs/docsite/rst/os_guide/windows_dsc.rst
@@ -0,0 +1,508 @@
+.. _windows_dsc:
+
+Desired State Configuration
+===========================
+
+.. contents:: Topics
+ :local:
+
+What is Desired State Configuration?
+````````````````````````````````````
+Desired State Configuration, or DSC, is a tool built into PowerShell that can
+be used to define a Windows host setup through code. The overall purpose of DSC
+is the same as Ansible, it is just executed in a different manner. Since
+Ansible 2.4, the ``win_dsc`` module has been added and can be used to take advantage of
+existing DSC resources when interacting with a Windows host.
+
+More details on DSC can be viewed at `DSC Overview <https://docs.microsoft.com/en-us/powershell/scripting/dsc/overview?view=powershell-7.2>`_.
+
+Host Requirements
+`````````````````
+To use the ``win_dsc`` module, a Windows host must have PowerShell v5.0 or
+newer installed. All supported hosts can be upgraded to PowerShell v5.
+
+Once the PowerShell requirements have been met, using DSC is as simple as
+creating a task with the ``win_dsc`` module.
+
+Why Use DSC?
+````````````
+DSC and Ansible modules have a common goal which is to define and ensure the state of a
+resource. Because of
+this, resources like the DSC `File resource <https://docs.microsoft.com/en-us/powershell/scripting/dsc/reference/resources/windows/fileresource>`_
+and Ansible ``win_file`` can be used to achieve the same result. Deciding which to use depends
+on the scenario.
+
+Reasons for using an Ansible module over a DSC resource:
+
+* The host does not support PowerShell v5.0, or it cannot easily be upgraded
+* The DSC resource does not offer a feature present in an Ansible module. For example,
+ win_regedit can manage the ``REG_NONE`` property type, while the DSC
+ ``Registry`` resource cannot
+* DSC resources have limited check mode support, while some Ansible modules have
+ better checks
+* DSC resources do not support diff mode, while some Ansible modules do
+* Custom resources require further installation steps to be run on the host
+ beforehand, while Ansible modules are built-in to Ansible
+* There are bugs in a DSC resource where an Ansible module works
+
+Reasons for using a DSC resource over an Ansible module:
+
+* The Ansible module does not support a feature present in a DSC resource
+* There is no Ansible module available
+* There are bugs in an existing Ansible module
+
+In the end, it doesn't matter whether the task is performed with DSC or an
+Ansible module; what matters is that the task is performed correctly and the
+playbooks are still readable. If you have more experience with DSC over Ansible
+and it does the job, just use DSC for that task.
+
+How to Use DSC?
+```````````````
+The ``win_dsc`` module takes in a free-form of options so that it changes
+according to the resource it is managing. A list of built-in resources can be
+found at `resources <https://docs.microsoft.com/en-us/powershell/scripting/dsc/resources/resources>`_.
+
+Using the `Registry <https://docs.microsoft.com/en-us/powershell/scripting/dsc/reference/resources/windows/registryresource>`_
+resource as an example, this is the DSC definition as documented by Microsoft:
+
+.. code-block:: powershell
+
+ Registry [string] #ResourceName
+ {
+ Key = [string]
+ ValueName = [string]
+ [ Ensure = [string] { Enable | Disable } ]
+ [ Force = [bool] ]
+ [ Hex = [bool] ]
+ [ DependsOn = [string[]] ]
+ [ ValueData = [string[]] ]
+ [ ValueType = [string] { Binary | Dword | ExpandString | MultiString | Qword | String } ]
+ }
+
+When defining the task, ``resource_name`` must be set to the DSC resource being
+used - in this case, the ``resource_name`` should be set to ``Registry``. The
+``module_version`` can refer to a specific version of the DSC resource
+installed; if left blank it will default to the latest version. The other
+options are parameters that are used to define the resource, such as ``Key`` and
+``ValueName``. While the options in the task are not case sensitive,
+keeping the case as-is is recommended because 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:
+
+.. code-block:: yaml+jinja
+
+ - name: Use win_dsc module with the Registry DSC resource
+ win_dsc:
+ resource_name: Registry
+ Ensure: Present
+ Key: HKEY_LOCAL_MACHINE\SOFTWARE\ExampleKey
+ ValueName: TestValue
+ ValueData: TestData
+
+Starting in Ansible 2.8, the ``win_dsc`` module automatically validates the
+input options from Ansible with the DSC definition. This means Ansible will
+fail if the option name is incorrect, a mandatory option is not set, or the
+value is not a valid choice. When running Ansible with a verbosity level of 3
+or more (``-vvv``), the return value will contain the possible invocation
+options based on the ``resource_name`` specified. Here is an example of the
+invocation output for the above ``Registry`` task:
+
+.. code-block:: ansible-output
+
+ changed: [2016] => {
+ "changed": true,
+ "invocation": {
+ "module_args": {
+ "DependsOn": null,
+ "Ensure": "Present",
+ "Force": null,
+ "Hex": null,
+ "Key": "HKEY_LOCAL_MACHINE\\SOFTWARE\\ExampleKey",
+ "PsDscRunAsCredential_password": null,
+ "PsDscRunAsCredential_username": null,
+ "ValueData": [
+ "TestData"
+ ],
+ "ValueName": "TestValue",
+ "ValueType": null,
+ "module_version": "latest",
+ "resource_name": "Registry"
+ }
+ },
+ "module_version": "1.1",
+ "reboot_required": false,
+ "verbose_set": [
+ "Perform operation 'Invoke CimMethod' with following parameters, ''methodName' = ResourceSet,'className' = MSFT_DSCLocalConfigurationManager,'namespaceName' = root/Microsoft/Windows/DesiredStateConfiguration'.",
+ "An LCM method call arrived from computer SERVER2016 with user sid S-1-5-21-3088887838-4058132883-1884671576-1105.",
+ "[SERVER2016]: LCM: [ Start Set ] [[Registry]DirectResourceAccess]",
+ "[SERVER2016]: [[Registry]DirectResourceAccess] (SET) Create registry key 'HKLM:\\SOFTWARE\\ExampleKey'",
+ "[SERVER2016]: [[Registry]DirectResourceAccess] (SET) Set registry key value 'HKLM:\\SOFTWARE\\ExampleKey\\TestValue' to 'TestData' of type 'String'",
+ "[SERVER2016]: LCM: [ End Set ] [[Registry]DirectResourceAccess] in 0.1930 seconds.",
+ "[SERVER2016]: LCM: [ End Set ] in 0.2720 seconds.",
+ "Operation 'Invoke CimMethod' complete.",
+ "Time taken for configuration job to complete is 0.402 seconds"
+ ],
+ "verbose_test": [
+ "Perform operation 'Invoke CimMethod' with following parameters, ''methodName' = ResourceTest,'className' = MSFT_DSCLocalConfigurationManager,'namespaceName' = root/Microsoft/Windows/DesiredStateConfiguration'.",
+ "An LCM method call arrived from computer SERVER2016 with user sid S-1-5-21-3088887838-4058132883-1884671576-1105.",
+ "[SERVER2016]: LCM: [ Start Test ] [[Registry]DirectResourceAccess]",
+ "[SERVER2016]: [[Registry]DirectResourceAccess] Registry key 'HKLM:\\SOFTWARE\\ExampleKey' does not exist",
+ "[SERVER2016]: LCM: [ End Test ] [[Registry]DirectResourceAccess] False in 0.2510 seconds.",
+ "[SERVER2016]: LCM: [ End Set ] in 0.3310 seconds.",
+ "Operation 'Invoke CimMethod' complete.",
+ "Time taken for configuration job to complete is 0.475 seconds"
+ ]
+ }
+
+The ``invocation.module_args`` key shows the actual values that were set as
+well as other possible values that were not set. Unfortunately, this will not
+show the default value for a DSC property, only what was set from the Ansible
+task. Any ``*_password`` option will be masked in the output for security
+reasons; if there are any other sensitive module options, set ``no_log: True``
+on the task to stop all task output from being logged.
+
+
+Property Types
+--------------
+Each DSC resource property has a type that is associated with it. Ansible
+will try to convert the defined options to the correct type during execution.
+For simple types like ``[string]`` and ``[bool]``, this is a simple operation,
+but complex types like ``[PSCredential]`` or arrays (like ``[string[]]``)
+require certain rules.
+
+PSCredential
+++++++++++++
+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:
+
+.. code-block:: yaml+jinja
+
+ PsDscRunAsCredential_username: '{{ ansible_user }}'
+ PsDscRunAsCredential_password: '{{ ansible_password }}'
+
+ SourceCredential_username: AdminUser
+ SourceCredential_password: PasswordForAdminUser
+
+.. Note:: On versions of Ansible older than 2.8, you should set ``no_log: true``
+ on the task definition in Ansible to ensure any credentials used are not
+ stored in any log file or console output.
+
+A ``[PSCredential]`` is defined with ``EmbeddedInstance("MSFT_Credential")`` in
+a DSC resource MOF definition.
+
+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:
+
+.. code-block:: yaml+jinja
+
+ # [CimInstance]AuthenticationInfo == MSFT_xWebAuthenticationInformation
+ AuthenticationInfo:
+ Anonymous: false
+ Basic: true
+ Digest: false
+ Windows: true
+
+In the above example, the CIM instance is a representation of the class
+`MSFT_xWebAuthenticationInformation <https://github.com/dsccommunity/xWebAdministration/blob/master/source/DSCResources/MSFT_xWebSite/MSFT_xWebSite.schema.mof>`_.
+This class accepts four boolean variables, ``Anonymous``, ``Basic``,
+``Digest``, and ``Windows``. The keys to use in a ``[CimInstance]`` depend on
+the class it represents. Please read through the documentation of the resource
+to determine the keys that can be used and the types of each key value. The
+class definition is typically located in the ``<resource name>.schema.mof``.
+
+HashTable Type
+++++++++++++++
+A ``[HashTable]`` object is also a dictionary but does not have a strict set of
+keys that can/need to be defined. Like a ``[CimInstance]``, define it as a
+normal dictionary value in YAML. A ``[HashTable]]`` is defined with
+``EmbeddedInstance("MSFT_KeyValuePair")`` in a DSC resource MOF definition.
+
+Arrays
+++++++
+Simple type arrays like ``[string[]]`` or ``[UInt32[]]`` are defined as a list
+or as a comma-separated string which is 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:
+
+.. code-block:: yaml+jinja
+
+ # [string[]]
+ ValueData: entry1, entry2, entry3
+ ValueData:
+ - entry1
+ - entry2
+ - entry3
+
+ # [UInt32[]]
+ ReturnCode: 0,3010
+ ReturnCode:
+ - 0
+ - 3010
+
+Complex type arrays like ``[CimInstance[]]`` (array of dicts), can be defined
+like this example:
+
+.. code-block:: yaml+jinja
+
+ # [CimInstance[]]BindingInfo == MSFT_xWebBindingInformation
+ BindingInfo:
+ - Protocol: https
+ Port: 443
+ CertificateStoreName: My
+ CertificateThumbprint: C676A89018C4D5902353545343634F35E6B3A659
+ HostName: DSCTest
+ IPAddress: '*'
+ SSLFlags: 1
+ - Protocol: http
+ Port: 80
+ IPAddress: '*'
+
+The above example is an array with two values of the class `MSFT_xWebBindingInformation <https://github.com/dsccommunity/xWebAdministration/blob/master/source/DSCResources/MSFT_xWebSite/MSFT_xWebSite.schema.mof>`_.
+When defining a ``[CimInstance[]]``, be sure to read the resource documentation
+to find out what keys to use in the definition.
+
+DateTime
+++++++++
+A ``[DateTime]`` object is a DateTime string representing the date and time in
+the `ISO 8601 <https://www.w3.org/TR/NOTE-datetime>`_ date time format. The
+value for a ``[DateTime]`` field should be quoted in YAML to ensure the string
+is properly serialized to the Windows host. Here is an example of how to define
+a ``[DateTime]`` value in Ansible:
+
+.. code-block:: yaml+jinja
+
+ # As UTC-0 (No timezone)
+ DateTime: '2019-02-22T13:57:31.2311892+00:00'
+
+ # As UTC+4
+ DateTime: '2019-02-22T17:57:31.2311892+04:00'
+
+ # As UTC-4
+ DateTime: '2019-02-22T09:57:31.2311892-04:00'
+
+All the values above are equal to a UTC date time of February 22nd 2019 at
+1:57pm with 31 seconds and 2311892 milliseconds.
+
+Run As Another User
+-------------------
+By default, DSC runs each resource as the SYSTEM account and not the account
+that Ansible uses to run the module. This means that resources that are dynamically
+loaded based on a user profile, like the ``HKEY_CURRENT_USER`` registry hive,
+will be loaded under the ``SYSTEM`` profile. The parameter
+``PsDscRunAsCredential`` is a parameter that can be set for every DSC resource, and
+force the DSC engine to run under a different account. As
+``PsDscRunAsCredential`` has a type of ``PSCredential``, it is defined with the
+``_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:
+
+.. code-block:: yaml+jinja
+
+ - 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
+
+Custom DSC Resources
+````````````````````
+DSC resources are not limited to the built-in options from Microsoft. Custom
+modules can be installed to manage other resources that are not usually available.
+
+Finding Custom DSC Resources
+----------------------------
+You can use the
+`PSGallery <https://www.powershellgallery.com/>`_ to find custom resources, along with documentation on how to install them on a Windows host.
+
+The ``Find-DscResource`` cmdlet can also be used to find custom resources. For example:
+
+.. code-block:: powershell
+
+ # Find all DSC resources in the configured repositories
+ Find-DscResource
+
+ # Find all DSC resources that relate to SQL
+ Find-DscResource -ModuleName "*sql*"
+
+.. Note:: DSC resources developed by Microsoft that start with ``x`` means the
+ resource is experimental and comes with no support.
+
+Installing a Custom Resource
+----------------------------
+There are three ways that a DSC resource can be installed on a host:
+
+* Manually with the ``Install-Module`` cmdlet
+* Using the ``win_psmodule`` Ansible module
+* Saving the module manually and copying it to another host
+
+The following is an example of installing the ``xWebAdministration`` resources using
+``win_psmodule``:
+
+.. code-block:: yaml+jinja
+
+ - name: Install xWebAdministration DSC resource
+ win_psmodule:
+ name: xWebAdministration
+ state: present
+
+Once installed, the win_dsc module will be able to use the resource by referencing it
+with the ``resource_name`` option.
+
+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:
+
+.. code-block:: powershell
+
+ Save-Module -Name xWebAdministration -Path C:\temp
+
+This will create a folder called ``xWebAdministration`` in ``C:\temp``, which
+can be copied to any host. For PowerShell to see this offline resource, it must
+be copied to a directory set in the ``PSModulePath`` environment variable.
+In most cases, the path ``C:\Program Files\WindowsPowerShell\Module`` is set
+through this variable, but the ``win_path`` module can be used to add different
+paths.
+
+Examples
+````````
+Extract a zip file
+------------------
+
+.. code-block:: yaml+jinja
+
+ - name: Extract a zip file
+ win_dsc:
+ resource_name: Archive
+ Destination: C:\temp\output
+ Path: C:\temp\zip.zip
+ Ensure: Present
+
+Create a directory
+------------------
+
+.. code-block:: yaml+jinja
+
+ - name: Create file with some text
+ win_dsc:
+ resource_name: File
+ DestinationPath: C:\temp\file
+ Contents: |
+ Hello
+ World
+ Ensure: Present
+ Type: File
+
+ - name: Create directory that is hidden is set with the System attribute
+ win_dsc:
+ resource_name: File
+ DestinationPath: C:\temp\hidden-directory
+ Attributes: Hidden,System
+ Ensure: Present
+ Type: Directory
+
+Interact with Azure
+-------------------
+
+.. code-block:: yaml+jinja
+
+ - name: Install xAzure DSC resources
+ win_psmodule:
+ name: xAzure
+ state: present
+
+ - name: Create virtual machine in Azure
+ win_dsc:
+ resource_name: xAzureVM
+ ImageName: a699494373c04fc0bc8f2bb1389d6106__Windows-Server-2012-R2-201409.01-en.us-127GB.vhd
+ Name: DSCHOST01
+ ServiceName: ServiceName
+ StorageAccountName: StorageAccountName
+ InstanceSize: Medium
+ Windows: true
+ Ensure: Present
+ Credential_username: '{{ ansible_user }}'
+ Credential_password: '{{ ansible_password }}'
+
+Setup IIS Website
+-----------------
+
+.. code-block:: yaml+jinja
+
+ - name: Install xWebAdministration module
+ win_psmodule:
+ name: xWebAdministration
+ state: present
+
+ - name: Install IIS features that are required
+ win_dsc:
+ resource_name: WindowsFeature
+ Name: '{{ item }}'
+ Ensure: Present
+ loop:
+ - Web-Server
+ - Web-Asp-Net45
+
+ - name: Setup web content
+ win_dsc:
+ resource_name: File
+ DestinationPath: C:\inetpub\IISSite\index.html
+ Type: File
+ Contents: |
+ <html>
+ <head><title>IIS Site</title></head>
+ <body>This is the body</body>
+ </html>
+ Ensure: present
+
+ - name: Create new website
+ win_dsc:
+ resource_name: xWebsite
+ Name: NewIISSite
+ State: Started
+ PhysicalPath: C:\inetpub\IISSite\index.html
+ BindingInfo:
+ - Protocol: https
+ Port: 8443
+ CertificateStoreName: My
+ CertificateThumbprint: C676A89018C4D5902353545343634F35E6B3A659
+ HostName: DSCTest
+ IPAddress: '*'
+ SSLFlags: 1
+ - Protocol: http
+ Port: 8080
+ IPAddress: '*'
+ AuthenticationInfo:
+ Anonymous: false
+ Basic: true
+ Digest: false
+ Windows: true
+
+.. seealso::
+
+ :ref:`playbooks_intro`
+ An introduction to playbooks
+ :ref:`playbooks_best_practices`
+ Tips and tricks for playbooks
+ :ref:`List of Windows Modules <windows_modules>`
+ Windows specific module list, all implemented in PowerShell
+ `User Mailing List <https://groups.google.com/group/ansible-project>`_
+ Have a question? Stop by the google group!
+ :ref:`communication_irc`
+ How to join Ansible chat channels