Connecting VPN in Circleci WIndows Instance - windows

I am facing this error while connecting to VPN in circleci. Has anyone encountered this ?
Context: I wanted to deploy files to AWS Windows EC2 instance and I am doing that using ssh in cirleci. In my EC2 instance, I have added inbound rule in port 22 of SSH to only allow connections from VPN connected connection only.
Edit:
Here is my config file:
build-deploy:
working_directory: ~/repo
executor:
name: windows/default
steps:
- checkout
- restore_cache:
keys:
- v1-dependencies-{{ checksum "package-lock.json" }}
- v1-dependencies-
- run:
name: Install dependencies
command: npm install
- save_cache:
key: v1-dependencies-{{ checksum "package-lock.json" }}
paths:
- node_modules
- run:
name: Build
command: npm run build
- run:
name: Connect to VPN
command: .\.circleci\connectVPN.ps1
- run:
name: Install POSH-SSH
command: .\.circleci\install_posh_ssh.ps1
- run:
name: Update Host
command: .\.circleci\set_known_hosts.ps1
- run:
name: Deploy App into EC2
command: .\.circleci\ssh_deploy.ps1
connectVPN.ps1
$VPN_NAME = $env:VPN_NAME
$VPN_ADDRESS = $env:VPN_ADDRESS
$VPN_USERNAME = $env:VPN_USERNAME
$VPN_PASSWORD = $env:VPN_PASSWORD
# If VPN with this name is present, then remove it
if ([bool] (Get-VpnConnection -Name "$VPN_NAME")) {
# Remove it
Remove-VpnConnection -Name "$VPN_NAME" -Force
}
# Adds the new VPN Connection
Add-VpnConnection -Name "$VPN_NAME" -ServerAddress "$VPN_ADDRESS" -TunnelType Pptp -EncryptionLevel NoEncryption -AuthenticationMethod Pap -RememberCredential -PassThru
# Connect the VPN configuration
$code = (Start-Process rasdial -NoNewWindow -ArgumentList "$VPN_NAME $VPN_USERNAME $VPN_PASSWORD" -PassThru -Verbose -Wait).ExitCode
if ("$code" -eq "0") {
Write-Host "Create and connect to VPN server success" -ForegroundColor DarkGreen
} else {
# Error codes: https://support.microsoft.com/en-us/help/824864/list-of-error-codes-for-dial-up-connections-or-vpn-connections
if ("$code" -eq "691") {
Write-Host "Create and connect to VPN server failed with wrong username or password" -ForegroundColor DarkRed
} else {
Write-Host "Create and connect to VPN server failed with error code: $($code)" -ForegroundColor DarkRed
throw "$code"
}
}

Related

Use ODBC connection to managed Azure SQL Database

I need to run a SQL query on Azure SQL Database from an Ansible playbook.
My task is:
- name: Sql server - rights
vars:
sql_groups:
- { group_name: "{{ reader_group }}", db_access: "db_datareader" }
- { group_name: "{{ contributer_group }}", db_access: "db_datawriter" }
- { group_name: "{{ owner_group }}", db_access: "db_owner" }
community.general.odbc:
dsn: "Driver={ODBC Driver 13 for SQL Server};Server=tcp:{{ sql_server_host }},1433;Database={{ sql_server_db }};Uid={{ mssql_login_user }};Pwd={{ mssql_login_password }};Encrypt=yes;TrustServerCertificate=no;Connection Timeout=30;Authentication=ActiveDirectoryPassword"
query: |
CREATE USER ["{{ group_name }}"] FROM EXTERNAL PROVIDER
EXEC sp_addrolemember '{{ db_access }}', '{{ group_name }}'
loop: "{{ sql_groups }}"
When I run the playbook with the following command, Ansible tries to communicate via SSH.
ansible-playbook -i inventory.yml playbook.yml --check
The error is :
[WARNING]: Unhandled error in Python interpreter discovery for host XXXXXX: Failed to connect to the host via ssh: ssh: Could not resolve hostname XXXXXX: Name
or service not known
fatal: [XXXXXX]: UNREACHABLE! => {"changed": false, "msg": "Data could not be sent to remote host \"XXXXXX\". Make sure this host can be reached over ssh: ssh: Could not resolve hostname XXXXXX: Name or service not known\r\n", "unreachable": true}
I think I need to force the use of an ODBC connection with something like below (example is for Windows server) :
ansible_connection: winrm
ansible_port: 5986
ansible_winrm_transport: credssp
ansible_winrm_server_cert_validation: ignore
What should I do ?
ansible_port: 1433 ? And what other parameters ?
I don't see how to communicate via ODBC.

The term 'mvn' is not recognized as the name of a cmdlet in gitlab ci cd pipeline yaml file

trying build maven project using gitlab specific runner getting error
My .gitlab-ci.yml content
variables:
MAVEN_OPTS: -Dmaven.repo.local=.m2/repository
image: maven:latest
stages:
- build
- test
- package
- deploy
cache:
paths:
- .m2/repository
- target
build_job:
stage: build
tags:
- docker
script:
- echo "Maven compile started"
- "mvn compile"
test_job:
stage: test
tags:
- docker
script:
- echo "Maven test started"
- "mvn test"
package_job:
stage: package
tags:
- docker
script:
- echo "Maven packaging started"
- "mvn package"
Deploy_job:
stage: deploy
tags:
- docker
script:
- echo "Maven deploy started"
error : $ mvn compile
mvn : The term 'mvn' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the
spelling of the name, or if a path was included, verify that the path is correct and try again.
At C:\WINDOWS\TEMP\build_script1691068991\script.ps1:243 char:1
+ mvn compile
+ ~~~
+ CategoryInfo : ObjectNotFound: (mvn:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
Try using docker specific runner and set environment in your config.tomal file. My docker specific runner config is below.
[[runners]]
name = "Docker-runner"
url = "https://gitlab.com"
id = *******
token = "****************"
token_obtained_at = ***********
token_expires_at = **********
executor = "docker"
environment = ["MAVEN_HOME=C:/Softwares/Maven/apache-maven-3.8.6/bin"]
[runners.custom_build_dir]
[runners.cache]
MaxUploadedArchiveSize = 0
[runners.cache.s3]
[runners.cache.gcs]
[runners.cache.azure]
[runners.docker]
tls_verify = false
image = "latest"
privileged = false
disable_entrypoint_overwrite = false
oom_kill_disable = false
disable_cache = false
volumes = ["/cache"]
shm_size = 0

Ansible seems to ignore ansible_shell_type when set by set_fact

I have a playbook that first creates a virtual machine on a vSphere cluster. It uses hosts: localhost so the API is called by the ansible-runner. Creation of VM works fine. After the VM is created and up, I want to call a powershell script on the created VM.
At this point I run into below issue:
{
"unreachable": true,
"msg": "Failed to create temporary directory. In some cases, you may have been able to authenticate and did not have permissions on the target directory. Consider changing the remote tmp path in ansible.cfg to a path rooted in \"/tmp\", for more error information use -vvv. Failed command was: ( umask 77 && mkdir -p \"` echo ~/.ansible/tmp `\"&& mkdir \"` echo ~/.ansible/tmp/ansible-tmp-1641299382.7315738-32-66906511694241 `\" && echo ansible-tmp-1641299382.7315738-32-66906511694241=\"` echo ~/.ansible/tmp/ansible-tmp-1641299382.7315738-32-66906511694241 `\" ), exited with result 1",
"changed": false
}
It seems the play thinks it executes on a Linux machine. That's not curious at all, because gather_facts is set to false in the playbook. So the play cannot know it is a Windows VM.
I tried to mitigate that issue by firing below task before, but the issue remains the same.
- name: set shell type
set_fact:
ansible_shell_type: powershell
I also tried by also setting os_family before, without success.
- name: set os fam
set_fact:
ansible_os_family: 'Windows'
When I fire this task before, it correctly shows "powershell".
- name: DEBUG ansible_shell_type
debug:
var: ansible_shell_type
I am a little bit lost now, it looks like the task does not make use of ansible_shell_type.
- name: Windows - Regenerate ssh host keys
ansible.windows.win_powershell:
script: |
del "C:\ProgramData\ssh\ssh_host_*"
ssh-keygen.exe -A
$Account = New-Object -TypeName System.Security.Principal.NTAccount -ArgumentList 'NT AUTHORITY\SYSTEM';
$ItemList = Get-ChildItem -Path C:\ProgramData\ssh\ssh_host_* -Recurse;
foreach ($Item in $ItemList) {
$Acl = $null; # Reset the $Acl variable to $null
$Acl = Get-Acl -Path $Item.FullName;
$Acl.SetOwner($Account);
$Acl.SetGroup($Account);
Set-Acl -Path $Item.FullName -AclObject $Acl;
}
delegate_to: "{{ vm_ip_address }}"
Using - meta: reset_connection before does not make any difference, too.
I'm kinda lost right now. Hope anyone of you has an idea what I missed.
Thanks to Zeitounator!
The fix is as easy as adding vars directly to the task. The below result works as expected:
- name: Windows - Regenerate ssh host keys
ansible.windows.win_powershell:
script: |
del "C:\ProgramData\ssh\ssh_host_*"
ssh-keygen.exe -A
$Account = New-Object -TypeName System.Security.Principal.NTAccount -ArgumentList 'NT AUTHORITY\SYSTEM';
$ItemList = Get-ChildItem -Path C:\ProgramData\ssh\ssh_host_* -Recurse;
foreach ($Item in $ItemList) {
$Acl = $null; # Reset the $Acl variable to $null
$Acl = Get-Acl -Path $Item.FullName;
$Acl.SetOwner($Account);
$Acl.SetGroup($Account);
Set-Acl -Path $Item.FullName -AclObject $Acl;
}
delegate_to: "{{ vm_ip_address }}"
vars:
ansible_shell_type: powershell

Ansible change connection from winrm to ssh between task

I have had an issue with connecting to local_action when running my playbook, my playbook is used to create users in SQL Server and need to run local action to get generate random password
fatal: [w961412]: UNREACHABLE! => {"changed": false, "msg": "ntlm: HTTPConnectionPool(host='localhost', port=5985): Max retries exceeded with url: /wsman (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7f4572858790>: Failed to establish a new connection: [Errno 111] Connection refused',))", "unreachable": true}
task for ssh
- name: get random password
command: tr -dc 'A-HJ-NP-Za-km-z2-9' < /dev/urandom | dd bs=12 count=1 status=none
register: secret
tasks for winrm:
- name: Alter database credentials.
win_shell: |
sqlcmd -S {{ sql_hostname }},{{ SQL_PORT }} -E -q "alter login {{ dbuser }} with password=N'{{ secret.password }}'" -o alter.log
register: alter_result
Foremost, what you said is actually correct: you want a local action; I don't think it needs to connect back to your control host over ssh just to generate a password
So, I would expect you could use:
- name: get a random password
connection: local
shell: tr -dc 'A-HJ-NP-Za-km-z2-9' < /dev/urandom | dd bs=12 count=1 status=none
register: secret
- win_shell: |
echo "and now you are back to the normal playbook connection"
Your code snippet also had a bug in it by trying to use command: with a string containing a pipe -- shell operators are not supported by command:, that's why shell: exists
Then, separately, you don't have to use a bunch of shell commands, along with some magic tr string literal: ansible has a random password lookup such that you can:
- win_shell: |
sqlcmd -q "alter login with password=N'{{ item }}'"
register: alter_result
with_password: /dev/null length=12

Create a Windows AMI with packer and ansible on AWS

I want to create an aws windows AMI with packer and ansible.
I have tried many configuration, but I have still a problem of connection to the instance.
Here is my packer conf :
{
"builders": [{
"type": "amazon-ebs",
"access_key": "{{user `aws_access_key`}}",
"secret_key": "{{user `aws_secret_key`}}",
"region": "eu-west-1",
"source_ami": "ami-58a1a73e",
"instance_type": "m3.medium",
"ami_name": "aaa-windows-ami {{timestamp}}",
"user_data_file":"./test.ps",
"communicator": "winrm",
"winrm_username": "Administrator",
"winrm_use_ssl": true,
"winrm_insecure": true
}],
"provisioners": [
{
"type": "ansible",
"playbook_file": "./playbook.yml",
"extra_arguments": [
"--extra-vars", "ansible_user=Administrator ansible_connection=winrm ansible_ssh_port=5986 ansible_winrm_server_cert_validation=ignore ansible_shell_type=powershell ansible_shell_executable=None"
]
},
{
"type": "powershell",
"script": "./init.ps1"
}
]
}
The User data script is activating winrm on the AWS instance.
<powershell>
write-output "Running User Data Script"
write-host "(host) Running User Data Script"
Set-ExecutionPolicy Unrestricted -Scope LocalMachine -Force -ErrorAction Ignore
# Don't set this before Set-ExecutionPolicy as it throws an error
$ErrorActionPreference = "stop"
# Remove HTTP listener
Remove-Item -Path WSMan:\Localhost\listener\listener* -Recurse
Set-Item WSMan:\localhost\MaxTimeoutms 1800000
Set-Item WSMan:\localhost\Service\Auth\Basic $true
$Cert = New-SelfSignedCertificate -CertstoreLocation Cert:\LocalMachine\My -DnsName "packer"
New-Item -Path WSMan:\LocalHost\Listener -Transport HTTPS -Address * -CertificateThumbPrint $Cert.Thumbprint -Force
# WinRM
write-output "Setting up WinRM"
write-host "(host) setting up WinRM"
cmd.exe /c winrm quickconfig -q
cmd.exe /c winrm set "winrm/config" '#{MaxTimeoutms="1800000"}'
cmd.exe /c winrm set "winrm/config/winrs" '#{MaxMemoryPerShellMB="1024"}'
cmd.exe /c winrm set "winrm/config/service" '#{AllowUnencrypted="true"}'
cmd.exe /c winrm set "winrm/config/client" '#{AllowUnencrypted="true"}'
cmd.exe /c winrm set "winrm/config/service/auth" '#{Basic="true"}'
cmd.exe /c winrm set "winrm/config/client/auth" '#{Basic="true"}'
cmd.exe /c winrm set "winrm/config/service/auth" '#{CredSSP="true"}'
cmd.exe /c winrm set "winrm/config/listener?Address=*+Transport=HTTPS" "#{Port=`"5986`";Hostname=`"packer`";CertificateThumbprint=`"$($Cert.Thumbprint)`"}"
cmd.exe /c netsh advfirewall firewall set rule group="remote administration" new enable=yes
cmd.exe /c netsh firewall add portopening TCP 5986 "Port 5986"
cmd.exe /c net stop winrm
cmd.exe /c sc config winrm start= auto
cmd.exe /c net start winrm
</powershell>
The error is.
==> amazon-ebs: Provisioning with Ansible...
amazon-ebs:
amazon-ebs: PLAY [all] *********************************************************************
amazon-ebs:
amazon-ebs: TASK [setup] *******************************************************************
amazon-ebs: fatal: [default]: UNREACHABLE! => {"changed": false, "msg": "ssl: auth method ssl requires a password", "unreachable": true}
amazon-ebs: to retry, use: --limit #/home/elhostis/repo/vagrant/playbook.retry
amazon-ebs:
amazon-ebs: PLAY RECAP *********************************************************************
amazon-ebs: default : ok=0 changed=0 unreachable=1 failed=0
amazon-ebs:
==> amazon-ebs: Terminating the source AWS instance...
==> amazon-ebs: Cleaning up any extra volumes...
==> amazon-ebs: No volumes to clean up, skipping
==> amazon-ebs: Deleting temporary security group...
==> amazon-ebs: Deleting temporary keypair...
I have also tried to create manually an AMI with a known username/password. Then, I have configured ansible with theses credentials, but I have this error.
==> amazon-ebs: Timeout waiting for password.
==> amazon-ebs: Terminating the source AWS instance...
==> amazon-ebs: Cleaning up any extra volumes...
==> amazon-ebs: No volumes to clean up, skipping
==> amazon-ebs: Deleting temporary security group...
==> amazon-ebs: Deleting temporary keypair...
Build 'amazon-ebs' errored: Timeout waiting for password.
Someone have an example to do that ?
Thanks a lot.
Eric
You need follow the instructions in the documentation for using the ansible provisioner with WinRM.
This is a working example running Windows 2016 Server Base:
{
"builders": [
{
"type": "amazon-ebs",
"region": "eu-west-1",
"instance_type": "m3.medium",
"source_ami": "ami-0983b56f",
"ami_name": "packer-demo-{{timestamp}}",
"user_data_file": "windows-userdata.txt",
"communicator": "winrm",
"winrm_username": "Administrator"
}],
"provisioners": [
{
"type": "ansible",
"playbook_file": "./win-playbook.yml",
"extra_arguments": [
"--connection", "packer", "-vvv",
"--extra-vars", "ansible_shell_type=powershell ansible_shell_executable=None"
]
}]
}
windows-userdata.txt
<powershell>
winrm quickconfig -q
winrm set winrm/config/winrs '#{MaxMemoryPerShellMB="300"}'
winrm set winrm/config '#{MaxTimeoutms="1800000"}'
winrm set winrm/config/service '#{AllowUnencrypted="true"}'
winrm set winrm/config/service/auth '#{Basic="true"}'
netsh advfirewall firewall add rule name="WinRM 5985" protocol=TCP dir=in localport=5985 action=allow
netsh advfirewall firewall add rule name="WinRM 5986" protocol=TCP dir=in localport=5986 action=allow
net stop winrm
sc config winrm start=auto
net start winrm
Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope LocalMachine
</powershell>
win-playbook.yml
---
- hosts: all
tasks:
- win_ping:
#- ping:
connection_plugins/packer.py
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from ansible.plugins.connection.ssh import Connection as SSHConnection
class Connection(SSHConnection):
''' ssh based connections for powershell via packer'''
transport = 'packer'
has_pipelining = True
become_methods = []
allow_executable = False
module_implementation_preferences = ('.ps1', '')
def __init__(self, *args, **kwargs):
super(Connection, self).__init__(*args, **kwargs)
Unfortunatley there seems to be a problem with the latest (2.3.0) version Ansible and Packer, see #4904
I don't find solution.
So, I don't use packer in my stack. I'm using only ansible. Here an example of code for other people.
#
# First, create a new instance
#
- hosts: localhost
tasks:
# Create a new instance with an AMI
- name: Create a new instance
ec2:
aws_access_key: "xxx"
aws_secret_key: "xxx"
region: "xxx"
key_name: "xxx"
instance_type: "t2.small"
image: "xxx"
assign_public_ip: yes
wait: yes
count: 1
register: ec2_created
# Wait a few minutes for windows starting
- name: Wait for windows is starting
pause:
minutes: 5
# Subscribe the new instance to ansible
- name: Subscribe host to Ansible
add_host:
name: "{{ec2_created.instances[0].dns_name}}"
groups: win
ansible_ssh_pass: "xxx"
no_log: True
#
# Then, provision the instance
#
- hosts: win
roles:
- xxx
#
# Finally, create a new AMI with the instance
# and destroy it
#
- hosts: localhost
tasks:
- name: Create AMI
ec2_ami:
aws_access_key: "xxx"
aws_secret_key: "xxx"
region: "xxx"
instance_id: "{{ec2_created.instance_ids[0]}}"
wait: yes
name: "xxx"
register: ami_created
- name: Destroy instance
ec2:
aws_access_key: "xxx"
aws_secret_key: "xxx"
region: "xxx"
state: 'absent'
instance_ids: "{{ec2_created.instance_ids[0]}}"

Resources