{"id":49726981,"url":"https://github.com/rgl/aws-windows-vm","last_synced_at":"2026-05-09T05:03:24.007Z","repository":{"id":292931724,"uuid":"982414196","full_name":"rgl/aws-windows-vm","owner":"rgl","description":"  An example Windows VM running in a AWS EC2 Instance ","archived":false,"fork":false,"pushed_at":"2025-07-29T06:47:57.000Z","size":57,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-07-29T08:51:55.899Z","etag":null,"topics":["aws","aws-ec2","ssh","terraform","windows","winrm"],"latest_commit_sha":null,"homepage":"","language":"HCL","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rgl.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-05-12T21:07:19.000Z","updated_at":"2025-07-29T06:48:01.000Z","dependencies_parsed_at":"2025-05-12T22:24:24.742Z","dependency_job_id":"f4c2a8e6-662e-46ca-b4a0-fddcb824ea29","html_url":"https://github.com/rgl/aws-windows-vm","commit_stats":null,"previous_names":["rgl/aws-windows-vm"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/rgl/aws-windows-vm","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rgl%2Faws-windows-vm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rgl%2Faws-windows-vm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rgl%2Faws-windows-vm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rgl%2Faws-windows-vm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rgl","download_url":"https://codeload.github.com/rgl/aws-windows-vm/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rgl%2Faws-windows-vm/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32807861,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-08T08:22:46.396Z","status":"online","status_checked_at":"2026-05-09T02:00:06.633Z","response_time":123,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aws","aws-ec2","ssh","terraform","windows","winrm"],"created_at":"2026-05-09T05:03:22.885Z","updated_at":"2026-05-09T05:03:23.982Z","avatar_url":"https://github.com/rgl.png","language":"HCL","funding_links":[],"categories":[],"sub_categories":[],"readme":"# About\n\n[![Lint](https://github.com/rgl/aws-windows-vm/actions/workflows/lint.yml/badge.svg)](https://github.com/rgl/aws-windows-vm/actions/workflows/lint.yml)\n\nAn example Windows VM running in a AWS EC2 Instance.\n\nThis will:\n\n* Create a VPC.\n  * Configure a Internet Gateway.\n* Create a Systems Manager ([aka SSM](https://docs.aws.amazon.com/systems-manager/latest/userguide/what-is-systems-manager.html#service-naming-history)) Parameter.\n* Create a EC2 Instance.\n  * Assign a Public IP IPv4 address.\n  * Assign a Public IP IPv6 address.\n  * Assign a IAM Role.\n    * Include the [AmazonSSMManagedInstanceCore Policy](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AmazonSSMManagedInstanceCore.html).\n  * Initialize.\n    * Configure WinRM.\n    * Configure SSH.\n    * Install a example application.\n      * Get the [Instance Identity Document](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-identity-documents.html) from the [EC2 Instance Metadata Service](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html).\n      * Get a Parameter from the [Systems Manager Parameter Store](https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-parameter-store.html).\n      * Get the [Instance (IAM) Role Credentials](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html#instance-metadata-security-credentials).\n  * Wait for the instance to be ready.\n\n# Usage (on a Ubuntu Desktop)\n\nInstall Visual Studio Code and the Dev Container plugin.\n\nInstall the dependencies:\n\n* [Visual Studio Code](https://code.visualstudio.com).\n* [Dev Container plugin](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers).\n\nOpen this directory with the Dev Container plugin.\n\nOpen the Visual Studio Code Terminal.\n\nSet the AWS Account credentials using SSO, e.g.:\n\n```bash\n# set the account credentials.\n# NB the aws cli stores these at ~/.aws/config.\n# NB this is equivalent to manually configuring SSO using aws configure sso.\n# see https://docs.aws.amazon.com/cli/latest/userguide/sso-configure-profile-token.html#sso-configure-profile-token-manual\n# see https://docs.aws.amazon.com/cli/latest/userguide/sso-configure-profile-token.html#sso-configure-profile-token-auto-sso\ncat \u003esecrets.sh \u003c\u003c'EOF'\n# set the environment variables to use a specific profile.\n# NB use aws configure sso to configure these manually.\n# e.g. use the pattern \u003caws-sso-session\u003e-\u003caws-account-id\u003e-\u003caws-role-name\u003e\nexport aws_sso_session='example'\nexport aws_sso_start_url='https://example.awsapps.com/start'\nexport aws_sso_region='eu-west-1'\nexport aws_sso_account_id='123456'\nexport aws_sso_role_name='AdministratorAccess'\nexport AWS_PROFILE=\"$aws_sso_session-$aws_sso_account_id-$aws_sso_role_name\"\nunset AWS_ACCESS_KEY_ID\nunset AWS_SECRET_ACCESS_KEY\nunset AWS_DEFAULT_REGION\n# configure the ~/.aws/config file.\n# NB unfortunately, I did not find a way to create the [sso-session] section\n#    inside the ~/.aws/config file using the aws cli. so, instead, manage that\n#    file using python.\npython3 \u003c\u003c'PY_EOF'\nimport configparser\nimport os\naws_sso_session = os.getenv('aws_sso_session')\naws_sso_start_url = os.getenv('aws_sso_start_url')\naws_sso_region = os.getenv('aws_sso_region')\naws_sso_account_id = os.getenv('aws_sso_account_id')\naws_sso_role_name = os.getenv('aws_sso_role_name')\naws_profile = os.getenv('AWS_PROFILE')\nconfig = configparser.ConfigParser()\naws_config_directory_path = os.path.expanduser('~/.aws')\naws_config_path = os.path.join(aws_config_directory_path, 'config')\nif os.path.exists(aws_config_path):\n  config.read(aws_config_path)\nconfig[f'sso-session {aws_sso_session}'] = {\n  'sso_start_url': aws_sso_start_url,\n  'sso_region': aws_sso_region,\n  'sso_registration_scopes': 'sso:account:access',\n}\nconfig[f'profile {aws_profile}'] = {\n  'sso_session': aws_sso_session,\n  'sso_account_id': aws_sso_account_id,\n  'sso_role_name': aws_sso_role_name,\n  'region': aws_sso_region,\n}\nos.makedirs(aws_config_directory_path, mode=0o700, exist_ok=True)\nwith open(aws_config_path, 'w') as f:\n  config.write(f)\nPY_EOF\nunset aws_sso_start_url\nunset aws_sso_region\nunset aws_sso_session\nunset aws_sso_account_id\nunset aws_sso_role_name\n# show the user, user amazon resource name (arn), and the account id, of the\n# profile set in the AWS_PROFILE environment variable.\nif ! aws sts get-caller-identity \u003e/dev/null 2\u003e\u00261; then\n  aws sso login\nfi\naws sts get-caller-identity\nEOF\n```\n\nOr, set the AWS Account credentials using an Access Key, e.g.:\n\n```bash\n# set the account credentials.\n# NB get these from your aws account iam console.\n#    see Managing access keys (console) at\n#        https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html#Using_CreateAccessKey\ncat \u003esecrets.sh \u003c\u003c'EOF'\nexport AWS_ACCESS_KEY_ID='TODO'\nexport AWS_SECRET_ACCESS_KEY='TODO'\nunset AWS_PROFILE\n# set the default region.\nexport AWS_DEFAULT_REGION='eu-west-1'\n# show the user, user amazon resource name (arn), and the account id.\naws sts get-caller-identity\nEOF\n```\n\nReview `main.tf`.\n\nLoad the secrets into the current shell session:\n\n```bash\nsource secrets.sh\n```\n\nInitialize terraform:\n\n```bash\nmake terraform-init\n```\n\nLaunch the example:\n\n```bash\nrm -f terraform.log\nmake terraform-apply\n```\n\nShow the terraform state:\n\n```bash\nmake terraform-show\n```\n\nShow the `Administrator` user password:\n\n```bash\nwhile true; do\n  administrator_password=\"$(aws ec2 get-password-data \\\n    --instance-id \"$(terraform output --raw app_instance_id)\" \\\n    --priv-launch-key ~/.ssh/id_rsa \\\n    | jq -r .PasswordData)\"\n  if [ -n \"$administrator_password\" ]; then\n    echo \"Administrator password: $administrator_password\"\n    break\n  fi\n  sleep 5\ndone\n```\n\nConnect to the instance RDP server as the `Administrator` user:\n\n**NB** This does not run from the dev container, so you should echo it here,\nand then execute the resulting command on your host.\n\n```bash\nremmina \"rdp://Administrator@$(terraform output --raw app_ip_address)\"\nremmina \"rdp://Administrator@$(terraform output --raw app_ipv6_address)\"\n```\n\nDo a connectivity check for the WinRM server endpoint, which should return a\n`405 Method Not Allowed` status code when the server is ready and you can\nconnect to it:\n\n```bash\ncurl --verbose \"http://$(terraform output --raw app_ip_address):5985/wsman\"\n```\n\nRepeat, using IPv6, but you have to do it outside of the dev container, as it\ndoes not have IPv6 support:\n\n**NB** This does not run from the dev container, so you should echo it here,\nand then execute the resulting command on your host.\n\n```bash\ncurl --verbose \"http://[$(terraform output --raw app_ipv6_address)]:5985/wsman\"\n```\n\nTest the WinRM connection, which should not return any error:\n\n**NB** This does not run from the dev container, so you should echo it here,\nand then execute the resulting command on your host.\n\n**NB** You must first install the [`winps` container image](https://github.com/rgl/winps).\n\n```bash\nadministrator_password=\"$(aws ec2 get-password-data \\\n  --instance-id \"$(terraform output --raw app_instance_id)\" \\\n  --priv-launch-key ~/.ssh/id_rsa \\\n  | jq -r .PasswordData)\"\ndocker run --rm \\\n  \"--add-host=winrm.test:$(terraform output --raw app_ip_address)\" \\\n  winps \\\n  winps \\\n  execute \\\n  --host=winrm.test \\\n  --encryption=auto \\\n  --username=Administrator \\\n  \"--password=$administrator_password\"\n```\n\nGet the instance ssh host public keys, convert them to the knowns hosts format,\nand show their fingerprints:\n\n```bash\n./aws-ssm-get-sshd-public-keys.sh \\\n  \"$(terraform output --raw app_instance_id)\" \\\n  | tail -2 \\\n  | jq -r .sshd_public_keys \\\n  | sed \"s/^/$(terraform output --raw app_instance_id),$(terraform output --raw app_ip_address),$(terraform output --raw app_ipv6_address) /\" \\\n  \u003e app-ssh-known-hosts.txt\nssh-keygen -l -f app-ssh-known-hosts.txt\n```\n\nUsing your ssh client, open a shell inside the VM and execute some commands:\n\n```bash\nssh \\\n  -o UserKnownHostsFile=app-ssh-known-hosts.txt \\\n  \"Administrator@$(terraform output --raw app_ip_address)\"\npowershell\n$PSVersionTable\nwhoami /all\nwinrm id\nwinrm enumerate winrm/config/listener\nwinrm get winrm/config\n\u0026\"C:\\Program Files\\Amazon\\SSM\\ssm-cli.exe\" get-instance-information\n\u0026\"C:\\Program Files\\Amazon\\SSM\\ssm-cli.exe\" get-diagnostics\n# List all the AWS endpoints that the SSM agent uses\n\u0026\"C:\\Program Files\\Amazon\\SSM\\ssm-cli.exe\" get-diagnostics |\n  Select-String -Pattern '([a-z0-9.-]+\\.amazonaws\\.com)' -AllMatches |\n  ForEach-Object { $_.Matches.Groups[1].Value } |\n  Sort-Object -Unique |\n  ForEach-Object {\n    $endpoint = $_\n    (Resolve-DnsName -Name $endpoint -Type A -QuickTimeout).IPAddress |\n    Sort-Object |\n    ForEach-Object { \"$endpoint`: $_\" }\n    (Resolve-DnsName -Name $endpoint -Type AAAA -QuickTimeout).IPAddress |\n    Sort-Object |\n    ForEach-Object { \"$endpoint`: $_\" }\n  }\ncurl.exe --verbose http://localhost/try\ncurl.exe --verbose 'http://[::1]/try'\nexit # exit the powershell.exe shell.\nexit # exit the cmd.exe shell.\n```\n\nUsing your ssh client, access using ipv6:\n\n**NB** This does not run from the dev container, so you should echo it here,\nand then execute the resulting command on your host.\n\n```bash\nssh \\\n  -6 \\\n  -o UserKnownHostsFile=app-ssh-known-hosts.txt \\\n  \"Administrator@$(terraform output --raw app_ipv6_address)\"\necho %SSH_CLIENT%\necho %SSH_CONNECTION%\ncurl -6 https://ip6.me/api/\nexit\n```\n\nUsing your ssh client, and [aws ssm session manager to proxy the ssh connection](https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-getting-started-enable-ssh-connections.html), open a shell inside the VM and execute some commands:\n\n```bash\nssh \\\n  -o UserKnownHostsFile=app-ssh-known-hosts.txt \\\n  -o ProxyCommand='aws ssm start-session --target %h --document-name AWS-StartSSHSession --parameters portNumber=%p' \\\n  \"Administrator@$(terraform output --raw app_instance_id)\"\npowershell\n$PSVersionTable\nwhoami /all\n\u0026\"C:\\Program Files\\Amazon\\SSM\\ssm-cli.exe\" get-instance-information\n\u0026\"C:\\Program Files\\Amazon\\SSM\\ssm-cli.exe\" get-diagnostics\ncurl.exe --verbose http://localhost/try\ncurl.exe --verbose 'http://[::1]/try'\nexit # exit the powershell.exe shell.\nexit # exit the cmd.exe shell.\n```\n\nUsing [aws ssm session manager](https://docs.aws.amazon.com/cli/latest/reference/ssm/start-session.html), open a `powershell` shell inside the VM and execute some commands:\n\n```bash\n# NB this executes the command inside a windows powershell shell. to switch to a\n#    different one, see the next example.\n# NB the default ssm session --document-name is SSM-SessionManagerRunShell.\n#    NB that document is created in our account when session manager is used\n#       for the first time.\n# see https://docs.aws.amazon.com/systems-manager/latest/userguide/getting-started-default-session-document.html\n# see aws ssm describe-document --name SSM-SessionManagerRunShell\naws ssm start-session --target \"$(terraform output --raw app_instance_id)\"\n$PSVersionTable\nwhoami /all\n\u0026\"C:\\Program Files\\Amazon\\SSM\\ssm-cli.exe\" get-instance-information\n\u0026\"C:\\Program Files\\Amazon\\SSM\\ssm-cli.exe\" get-diagnostics\ncurl.exe --verbose http://localhost/try\ncurl.exe --verbose 'http://[::1]/try'\nexit # exit the powershell.exe shell.\n```\n\nUsing [aws ssm session manager](https://docs.aws.amazon.com/cli/latest/reference/ssm/start-session.html), open a `cmd` shell inside the VM and execute some commands:\n\n```bash\n# NB this executes the command inside a powershell shell, but we immediately\n#    start the cmd shell.\n# NB the default ssm session --document-name is SSM-SessionManagerRunShell which\n#    is created in our account when session manager is used the first time.\n# see aws ssm describe-document --name AWS-StartInteractiveCommand --query 'Document.Parameters[*]'\n# see aws ssm describe-document --name AWS-StartNonInteractiveCommand --query 'Document.Parameters[*]'\naws ssm start-session \\\n  --document-name AWS-StartInteractiveCommand \\\n  --parameters '{\"command\":[\"cmd.exe\"]}' \\\n  --target \"$(terraform output --raw app_instance_id)\"\nver\nwhoami /all\n\"C:\\Program Files\\Amazon\\SSM\\ssm-cli.exe\" get-instance-information\n\"C:\\Program Files\\Amazon\\SSM\\ssm-cli.exe\" get-diagnostics\ncurl --verbose http://localhost/try\ncurl --verbose http://[::1]/try\nexit\n```\n\nDestroy the example:\n\n```bash\nmake terraform-destroy\n```\n\n# References\n\n* [Environment variables to configure the AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html)\n* [Token provider configuration with automatic authentication refresh for AWS IAM Identity Center](https://docs.aws.amazon.com/cli/latest/userguide/sso-configure-profile-token.html) (SSO)\n* [Managing access keys (console)](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html#Using_CreateAccessKey)\n* [AWS General Reference](https://docs.aws.amazon.com/general/latest/gr/Welcome.html)\n  * [Amazon Resource Names (ARNs)](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)\n* [Connect to the internet using an internet gateway](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Internet_Gateway.html#vpc-igw-internet-access)\n* [Retrieve instance metadata](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instancedata-data-retrieval.html)\n* [How Instance Metadata Service Version 2 works](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-metadata-v2-how-it-works.html)\n* [Configure your Amazon EC2 Windows instance](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-windows-instances.html)\n* [How Amazon EC2 handles user data for Windows instances](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/user-data.html#ec2-windows-user-data)\n* [AWS Systems Manager (aka Amazon EC2 Simple Systems Manager (SSM))](https://docs.aws.amazon.com/systems-manager/latest/userguide/what-is-systems-manager.html)\n  * [Amazon SSM Agent Source Code Repository](https://github.com/aws/amazon-ssm-agent)\n  * [Amazon SSM Session Manager Plugin Source Code Repository](https://github.com/aws/session-manager-plugin)\n  * [AWS Systems Manager Session Manager](https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager.html)\n    * [Start a session](https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-working-with-sessions-start.html)\n      * [Starting a session (AWS CLI)](https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-working-with-sessions-start.html#sessions-start-cli)\n      * [Starting a session (SSH)](https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-working-with-sessions-start.html#sessions-start-ssh)\n        * [Allow and control permissions for SSH connections through Session Manager](https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-getting-started-enable-ssh-connections.html)\n      * [Starting a session (port forwarding)](https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-working-with-sessions-start.html#sessions-start-port-forwarding)\n* IPv6\n  * [IPv6 on AWS](https://docs.aws.amazon.com/whitepapers/latest/ipv6-on-aws/IPv6-on-AWS.html)\n  * [IPv6 support for your VPC](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-migrate-ipv6.html)\n  * [AWS and IPv6](https://www.youtube.com/watch?v=bJK5R_dJCBY)\n  * [Architect and build IPv6 networks on AWS](https://www.youtube.com/watch?v=zRILaf5JeTM)\n\n# Alternatives\n\n* https://github.com/terraform-aws-modules\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frgl%2Faws-windows-vm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frgl%2Faws-windows-vm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frgl%2Faws-windows-vm/lists"}