Skip to content

Commit b702add

Browse files
authored
Merge pull request #5 from timoa/develop
Use Ansible with Terraform to configure the instance at boot time
2 parents 623a97d + c03933b commit b702add

35 files changed

+435
-183
lines changed

.github/workflows/code-review.yml

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ jobs:
1818
TF_VAR_region: ${{secrets.OCI_REGION}}
1919

2020
steps:
21+
- name: Harden GitHub Actions Runner
22+
uses: step-security/harden-runner@248ae51c2e8cc9622ecf50685c8bf7150c6e8813
23+
with:
24+
egress-policy: audit
25+
2126
- name: Checkout
2227
uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3.0.2
2328

@@ -26,16 +31,15 @@ jobs:
2631
# slow due to lack of caching
2732
# Note: Terraform is not needed for tflint
2833
- name: Install Terraform
29-
run: |
30-
brew install terraform
34+
run: brew install terraform
3135

3236
# Run init to get module code to be able to use `--module`
3337
- name: Terraform init
34-
run: |
35-
terraform init
38+
run: terraform init
39+
working-directory: ./terraform
3640

3741
# Run TFLint
38-
- name: tflint with reviewdog output on the PR
42+
- name: Run TFlint with reviewdog output on the PR
3943
uses: reviewdog/action-tflint@46e609666b039b775a150e84781ef79ea90089a8 # tag=v1.17.0
4044

4145
# -- SECURITY ---------------------------------------------------------------
@@ -52,9 +56,14 @@ jobs:
5256
TF_VAR_region: ${{secrets.OCI_REGION}}
5357

5458
steps:
59+
- name: Harden GitHub Actions Runner
60+
uses: step-security/harden-runner@248ae51c2e8cc9622ecf50685c8bf7150c6e8813
61+
with:
62+
egress-policy: audit
63+
5564
- name: Checkout
5665
uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3.0.2
5766

5867
# Run TFSec
59-
- name: Run tfsec with reviewdog output on the PR
68+
- name: Run TFsec with reviewdog output on the PR
6069
uses: reviewdog/action-tfsec@3f1d245c545329b13061259c2f126305893ad138 # tag=v1.15.0

.github/workflows/terraform.yml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ jobs:
1818
TF_VAR_region: ${{secrets.OCI_REGION}}
1919

2020
steps:
21+
- name: Harden GitHub Actions Runner
22+
uses: step-security/harden-runner@248ae51c2e8cc9622ecf50685c8bf7150c6e8813
23+
with:
24+
egress-policy: audit
25+
2126
- name: Checkout
2227
uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3.0.2
2328

@@ -27,14 +32,17 @@ jobs:
2732
- name: Terraform Format
2833
id: fmt
2934
run: terraform fmt -check
35+
working-directory: ./terraform
3036
continue-on-error: true
3137

3238
- name: Terraform Init
3339
id: init
40+
working-directory: ./terraform
3441
run: terraform init
3542

3643
- name: Terraform Plan
3744
id: apply
45+
working-directory: ./terraform
3846
run: terraform plan
3947

4048
# -- SAST SCAN --------------------------------------------------------------
@@ -46,6 +54,11 @@ jobs:
4654
if: (github.actor != 'dependabot[bot]')
4755

4856
steps:
57+
- name: Harden GitHub Actions Runner
58+
uses: step-security/harden-runner@248ae51c2e8cc9622ecf50685c8bf7150c6e8813
59+
with:
60+
egress-policy: audit
61+
4962
- name: Checkout
5063
uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3.0.2
5164

@@ -69,6 +82,11 @@ jobs:
6982
needs: tests
7083

7184
steps:
85+
- name: Harden GitHub Actions Runner
86+
uses: step-security/harden-runner@248ae51c2e8cc9622ecf50685c8bf7150c6e8813
87+
with:
88+
egress-policy: audit
89+
7290
- name: Checkout
7391
uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3.0.2
7492

@@ -92,6 +110,11 @@ jobs:
92110
if: github.ref == 'refs/heads/main'
93111

94112
steps:
113+
- name: Harden GitHub Actions Runner
114+
uses: step-security/harden-runner@248ae51c2e8cc9622ecf50685c8bf7150c6e8813
115+
with:
116+
egress-policy: audit
117+
95118
- name: Checkout
96119
uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3.0.2
97120
with:

.gitignore

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
# Local .terraform directories
2-
**/.terraform/*
2+
**/**/.terraform/*
33

44
# .tfstate files
5-
*.tfstate
6-
*.tfstate.*
5+
**/*.tfstate
6+
**/*.tfstate.*
77

88
# Crash log files
9-
crash.log
9+
**/crash.log
1010

1111
# Ignore any .tfvars files that are generated automatically for each Terraform run. Most
1212
# .tfvars files are managed as part of configuration and so should be included in
@@ -16,10 +16,10 @@ crash.log
1616

1717
# Ignore override files as they are usually used to override resources locally and so
1818
# are not checked in
19-
override.tf
20-
override.tf.json
21-
*_override.tf
22-
*_override.tf.json
19+
**/override.tf
20+
**/override.tf.json
21+
**/*_override.tf
22+
**/*_override.tf.json
2323

2424
# Include override files you do wish to add to version control using negated pattern
2525
#
@@ -29,4 +29,10 @@ override.tf.json
2929
# example: *tfplan*
3030

3131
# Key Pair files
32-
keypairs/**/*
32+
**/keypairs/**/*
33+
34+
# Ansible
35+
ansible/hosts.yml
36+
ansible/roles/**/*
37+
ansible/group_vars/**/*.yml
38+
ansible/host_vars/**/*.yml

README.md

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,46 @@
66

77
Terraform project that deploys VSCode Server on Oracle Cloud Infrastructure using only the free tier.
88

9-
> WARNING: This project is currently under developmnent.
9+
> WARNING: This project is currently under active development.
1010
> Please check back later.
1111
12+
## The challenge
13+
14+
### Goal
15+
16+
Deploy a free and easy maintenable VSCode Server.
17+
18+
### Limitations
19+
20+
Currently, Oracle Cloud Free tier provides great performance (4vCPU ARM based, 24GB of RAM, and 200GB of storage), but:
21+
22+
* The instance is preemptible, which means that they can be terminated at any time
23+
* We can't create custom images, so we have to install VSCode Server and other dependencies at boot time
24+
* Can be hard to find a OCI datacenter that has still available capacity
25+
26+
## How to start
27+
28+
### Create an OCI account
29+
30+
### Configure the OCI authentication
31+
32+
### Deploy the VSCode Server instance
33+
34+
### Access to VSCode Server from your browser
35+
1236
## TODO
1337

1438
- [x] Create the custom VCN (VPC)
1539
- [x] Get the latest Ubuntu image automatically
16-
- [x] Create the block volume for `/data` (150GB)
40+
- [x] Create the block volume for `/data` (100GB)
1741
- [x] Attach the block volume to the instance
1842
- [x] Create the instance on free tier (4 vCPU, 24GB memory)
1943
- [x] Configure the instance and install VSCode Server with Cloud Init
2044
- [x] Create automatically the SSH key pair
2145
- [x] Mount and format the block volume on `/data`
2246
- [x] Restrict SSH and VS Code port access
47+
- [x] Configure backups of the block volume only
2348
- [ ] Encrypt the block volume with a KMS key
24-
- [ ] Configure backups of the block volume only (WIP)
2549
- [ ] Configure Cloudflare Zero Trust to secure the instance access
2650
- [ ] Write the documentation for the manual steps (Oracle Cloud Infrastructure & Cloudflare accounts, etc.)
2751
- [ ] Explain how to avoid the "Out of Host capacity" error

USAGE.md

Lines changed: 4 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,84 +1,21 @@
11
<!-- BEGIN_TF_DOCS -->
22
## Requirements
33

4-
| Name | Version |
5-
|------|---------|
6-
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.0 |
7-
| <a name="requirement_cloudinit"></a> [cloudinit](#requirement\_cloudinit) | 2.2.0 |
8-
| <a name="requirement_local"></a> [local](#requirement\_local) | 2.2.2 |
9-
| <a name="requirement_null"></a> [null](#requirement\_null) | 3.1.1 |
10-
| <a name="requirement_oci"></a> [oci](#requirement\_oci) | 4.72.0 |
11-
| <a name="requirement_tls"></a> [tls](#requirement\_tls) | 3.4.0 |
4+
No requirements.
125

136
## Modules
147

158
No modules.
169

1710
## Resources
1811

19-
| Name | Type |
20-
|------|------|
21-
| [local_file.private_key_pem](https://registry.terraform.io/providers/hashicorp/local/2.2.2/docs/resources/file) | resource |
22-
| [local_file.public_key_openssh](https://registry.terraform.io/providers/hashicorp/local/2.2.2/docs/resources/file) | resource |
23-
| [null_resource.post_install](https://registry.terraform.io/providers/hashicorp/null/3.1.1/docs/resources/resource) | resource |
24-
| [null_resource.private_key_chmod](https://registry.terraform.io/providers/hashicorp/null/3.1.1/docs/resources/resource) | resource |
25-
| [null_resource.public_key_chmod](https://registry.terraform.io/providers/hashicorp/null/3.1.1/docs/resources/resource) | resource |
26-
| [oci_core_default_route_table.default_rt](https://registry.terraform.io/providers/oracle/oci/4.72.0/docs/resources/core_default_route_table) | resource |
27-
| [oci_core_instance.instance](https://registry.terraform.io/providers/oracle/oci/4.72.0/docs/resources/core_instance) | resource |
28-
| [oci_core_internet_gateway.igw](https://registry.terraform.io/providers/oracle/oci/4.72.0/docs/resources/core_internet_gateway) | resource |
29-
| [oci_core_security_list.security_list_ssh](https://registry.terraform.io/providers/oracle/oci/4.72.0/docs/resources/core_security_list) | resource |
30-
| [oci_core_security_list.security_list_vscode](https://registry.terraform.io/providers/oracle/oci/4.72.0/docs/resources/core_security_list) | resource |
31-
| [oci_core_subnet.subnet](https://registry.terraform.io/providers/oracle/oci/4.72.0/docs/resources/core_subnet) | resource |
32-
| [oci_core_vcn.vcn](https://registry.terraform.io/providers/oracle/oci/4.72.0/docs/resources/core_vcn) | resource |
33-
| [oci_core_volume.volume](https://registry.terraform.io/providers/oracle/oci/4.72.0/docs/resources/core_volume) | resource |
34-
| [oci_core_volume_attachment.volume_attachment](https://registry.terraform.io/providers/oracle/oci/4.72.0/docs/resources/core_volume_attachment) | resource |
35-
| [oci_core_volume_backup_policy_assignment.policy](https://registry.terraform.io/providers/oracle/oci/4.72.0/docs/resources/core_volume_backup_policy_assignment) | resource |
36-
| [tls_private_key.default](https://registry.terraform.io/providers/hashicorp/tls/3.4.0/docs/resources/private_key) | resource |
37-
| [cloudinit_config.cloudinit](https://registry.terraform.io/providers/hashicorp/cloudinit/2.2.0/docs/data-sources/config) | data source |
38-
| [oci_core_images.ubuntu_20_04_aarch64](https://registry.terraform.io/providers/oracle/oci/4.72.0/docs/data-sources/core_images) | data source |
39-
| [oci_core_volume_backup_policies.predefined_volume_backup_policies](https://registry.terraform.io/providers/oracle/oci/4.72.0/docs/data-sources/core_volume_backup_policies) | data source |
40-
| [oci_identity_availability_domains.ads](https://registry.terraform.io/providers/oracle/oci/4.72.0/docs/data-sources/identity_availability_domains) | data source |
12+
No resources.
4113

4214
## Inputs
4315

44-
| Name | Description | Type | Default | Required |
45-
|------|-------------|------|---------|:--------:|
46-
| <a name="input_namespace"></a> [namespace](#input\_namespace) | Project name that will be use to identifiy the resources | `string` | `"vscode"` | no |
47-
| <a name="input_stage"></a> [stage](#input\_stage) | Stage/environment name to tag and suffix the infrastructure composants | `string` | `"dev"` | no |
48-
| <a name="input_tenancy_ocid"></a> [tenancy\_ocid](#input\_tenancy\_ocid) | Tenancy OCID | `string` | `null` | no |
49-
| <a name="input_compartment_ocid"></a> [compartment\_ocid](#input\_compartment\_ocid) | Compartment OCID | `string` | `null` | no |
50-
| <a name="input_user_ocid"></a> [user\_ocid](#input\_user\_ocid) | User OCID | `string` | `null` | no |
51-
| <a name="input_fingerprint"></a> [fingerprint](#input\_fingerprint) | Fingerprint | `string` | `null` | no |
52-
| <a name="input_private_key"></a> [private\_key](#input\_private\_key) | Private Key content | `string` | `null` | no |
53-
| <a name="input_region"></a> [region](#input\_region) | Default Region | `string` | `"uk-london-1"` | no |
54-
| <a name="input_allowed_ingress_ssh"></a> [allowed\_ingress\_ssh](#input\_allowed\_ingress\_ssh) | List of IPs allowed to SSH on the instance | `list(string)` | `[]` | no |
55-
| <a name="input_allowed_egress_ssh"></a> [allowed\_egress\_ssh](#input\_allowed\_egress\_ssh) | List of IPs the instance is allowed to connect | `list(string)` | <pre>[<br> "0.0.0.0/0"<br>]</pre> | no |
56-
| <a name="input_allowed_ingress_vscode"></a> [allowed\_ingress\_vscode](#input\_allowed\_ingress\_vscode) | List of IPs allowed to access to VS Code Server | `list(string)` | `[]` | no |
57-
| <a name="input_allowed_egress_vscode"></a> [allowed\_egress\_vscode](#input\_allowed\_egress\_vscode) | List of IPs the instance is allowed to connect | `list(string)` | <pre>[<br> "0.0.0.0/0"<br>]</pre> | no |
58-
| <a name="input_instance_shape"></a> [instance\_shape](#input\_instance\_shape) | Instance Shape | `string` | `"VM.Standard.A1.Flex"` | no |
59-
| <a name="input_instance_ocpus"></a> [instance\_ocpus](#input\_instance\_ocpus) | Number of OCPUS (CPU cores) | `string` | `4` | no |
60-
| <a name="input_instance_shape_config_memory_in_gbs"></a> [instance\_shape\_config\_memory\_in\_gbs](#input\_instance\_shape\_config\_memory\_in\_gbs) | Memory in GBs | `string` | `24` | no |
61-
| <a name="input_instance_os"></a> [instance\_os](#input\_instance\_os) | Instance OS | `string` | `"Canonical Ubuntu"` | no |
62-
| <a name="input_instance_os_version"></a> [instance\_os\_version](#input\_instance\_os\_version) | Instance OS Version | `string` | `"20.04"` | no |
63-
| <a name="input_instance_os_user"></a> [instance\_os\_user](#input\_instance\_os\_user) | Instance User | `string` | `"ubuntu"` | no |
64-
| <a name="input_block_volume_size"></a> [block\_volume\_size](#input\_block\_volume\_size) | Block Volume size in GBs (/data) | `string` | `100` | no |
65-
| <a name="input_block_volume_device_name"></a> [block\_volume\_device\_name](#input\_block\_volume\_device\_name) | Block Volume device name (/dev/oracleoci/oraclevdb) | `string` | `"/dev/oracleoci/oraclevdb"` | no |
66-
| <a name="input_vscode_version"></a> [vscode\_version](#input\_vscode\_version) | VS Code Server Version | `string` | `"4.4.0"` | no |
67-
| <a name="input_keypair_name"></a> [keypair\_name](#input\_keypair\_name) | Name of the Key Pair (instance or service for ex.) | `string` | `null` | no |
68-
| <a name="input_keypair_public_key"></a> [keypair\_public\_key](#input\_keypair\_public\_key) | A pregenerated OpenSSH-formatted public key. Changing this creates a new keypair. If a public key is not specified, then a public/private key pair will be automatically generated. If a pair is created, then destroying this resource means you will lose access to that keypair forever. | `string` | `null` | no |
69-
| <a name="input_keypair_public_key_path"></a> [keypair\_public\_key\_path](#input\_keypair\_public\_key\_path) | Path to Public Key directory (e.g. `/keypairs`) | `string` | `"./keypairs"` | no |
70-
| <a name="input_keypair_key_algorithm"></a> [keypair\_key\_algorithm](#input\_keypair\_key\_algorithm) | Key Pair algorithm | `string` | `"RSA"` | no |
71-
| <a name="input_keypair_private_key"></a> [keypair\_private\_key](#input\_keypair\_private\_key) | A pregenerated OpenSSH-formatted private key. Changing this creates a new keypair. If a private key is not specified, then a public/private key pair will be automatically generated. If a pair is created, then destroying this resource means you will lose access to that keypair forever. | `string` | `null` | no |
72-
| <a name="input_keypair_private_key_extension"></a> [keypair\_private\_key\_extension](#input\_keypair\_private\_key\_extension) | Private key extension | `string` | `""` | no |
73-
| <a name="input_keypair_public_key_extension"></a> [keypair\_public\_key\_extension](#input\_keypair\_public\_key\_extension) | Public key extension | `string` | `".pub"` | no |
74-
| <a name="input_keypair_chmod_command_public"></a> [keypair\_chmod\_command\_public](#input\_keypair\_chmod\_command\_public) | Template of the command executed on the public key file | `string` | `"chmod 600 %v"` | no |
75-
| <a name="input_keypair_chmod_command_private"></a> [keypair\_chmod\_command\_private](#input\_keypair\_chmod\_command\_private) | Template of the command executed on the private key file | `string` | `"chmod 400 %v"` | no |
76-
| <a name="input_labels"></a> [labels](#input\_labels) | Default labels to associate to these resources | `map(string)` | <pre>{<br> "businessunit": "mycompany",<br> "project": "VSCode Server",<br> "team": "devops",<br> "terraform": "true"<br>}</pre> | no |
16+
No inputs.
7717

7818
## Outputs
7919

80-
| Name | Description |
81-
|------|-------------|
82-
| <a name="output_instance_private_ip"></a> [instance\_private\_ip](#output\_instance\_private\_ip) | VS Code Server Instance Private IP |
83-
| <a name="output_instance_public_ip"></a> [instance\_public\_ip](#output\_instance\_public\_ip) | VS Code Server Instance Public IP |
20+
No outputs.
8421
<!-- END_TF_DOCS -->

ansible/group_vars/server/.gitkeep

Whitespace-only changes.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
# This playbook install the common packages
3+
- hosts: server
4+
become: true
5+
6+
tasks:
7+
- name: Update apt-get repo and cache
8+
apt: update_cache=yes force_apt_get=yes cache_valid_time=3600
9+
10+
- name: Upgrade all apt packages
11+
apt: upgrade=dist force_apt_get=yes
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
---
2+
# This playbook install the common packages
3+
- hosts: server
4+
become: true
5+
gather_facts: false
6+
7+
tasks:
8+
- name: Install OpenJDK
9+
apt:
10+
name: openjdk-16-jdk
11+
state: present
12+
13+
- name: Install OpenJDK JRE
14+
apt:
15+
name: openjdk-16-jre-headless
16+
state: present
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
# This playbook install the common packages
3+
- hosts: server
4+
become: true
5+
gather_facts: false
6+
7+
tasks:
8+
- name: Reboot the server, wait for it to go down, come back up, and respond to the command "whoami"
9+
become: yes
10+
reboot:
11+
reboot_timeout: 600 # You can adapt the timeout to your needs

ansible/playbooks/common/roles.yml

Whitespace-only changes.

0 commit comments

Comments
 (0)