This is an automated email from the ASF dual-hosted git repository.

kezhenxu94 pushed a commit to branch modularity
in repository https://gitbox.apache.org/repos/asf/skywalking-terraform.git

commit 4c8fd20157e738452119d7951deda7fc758ae6ab
Author: kezhenxu94 <[email protected]>
AuthorDate: Sat Sep 2 14:36:35 2023 +0800

    Move skywalking cluster to a dedicated module and reorganize the doc
---
 .gitignore                                         |   1 +
 README.md                                          | 193 ++-------------------
 ansible/README.md                                  | 108 ++++++++++++
 aws/README.md                                      | 191 +++++++++++---------
 aws/alb-main.tf                                    |  22 ++-
 aws/{README.md => configurations.md}               |  24 +--
 aws/ec2-main.tf                                    |   8 +-
 aws/key-pair-output.tf                             |  21 ---
 aws/modules/skywalking/README.md                   |  72 ++++++++
 .../skywalking/main-bastion.tf}                    |  16 +-
 .../skywalking/main-data.tf}                       |   0
 .../skywalking/main-key-pair.tf}                   |   0
 .../skywalking/main-oap.tf}                        |  28 ++-
 .../skywalking/main-ui.tf}                         |  37 ++--
 aws/modules/skywalking/outputs.tf                  |  72 ++++++++
 aws/{ => modules/skywalking}/variables.tf          | 131 ++++++--------
 aws/rds-postgresql-main.tf                         |   2 +-
 aws/skywalking-main.tf                             |  40 +++++
 aws/skywalking-oap-output.tf                       |  22 ---
 aws/{bastion-output.tf => skywalking-outputs.tf}   |  19 +-
 aws/skywalking-ui-output.tf                        |  21 ---
 aws/variables.tf                                   |  21 ++-
 22 files changed, 589 insertions(+), 460 deletions(-)

diff --git a/.gitignore b/.gitignore
index 29354fb..5137481 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,3 +19,4 @@ ansible/local.var.yaml
 ansible/inventory
 !ansible/inventory/template
 .terraform.tfstate.lock.info
+terraform.tfvars
diff --git a/README.md b/README.md
index a8dfc52..09f22bc 100644
--- a/README.md
+++ b/README.md
@@ -6,195 +6,26 @@ no matter on-premises or on cloud vendors, such as AWS.
 
 # Terraform
 
-**Notice, HashiCorp had changed the LICENSE of Terraform from MPL 2.0 to 
BSL/BUSL 1.1 since its 1.5.6 release. We don't have hard-dependencies on 
Terraform.**
-
-**OpenTF Foundation announced to maintain the MPL 2.0 based fork of Terraform. 
Read their [announcement](https://opentf.org/announcement) and 
[website](https://opentf.org/) for more details.**
-
-**All Terraform and/or OpenTF scripts are just for end-user convenience. The 
Apache 2.0 License is only for the scripts.**
-
 For now, we have supported the following cloud vendors, and we welcome 
everyone to contribute supports for
 more cloud vendors:
 
-- Amazon Web Services (AWS): go to the [aws](aws) folder for more details.
-
-## Prerequisites
-
-1. Terraform installed
-2. AWS Credentials: Ensure your environment is set up with the necessary AWS 
credentials. This can be done in various ways, such as:
-  - Configuring using the AWS CLI.
-  - Setting up environment variables (`AWS_ACCESS_KEY_ID` and 
`AWS_SECRET_ACCESS_KEY`).
-  - Using IAM roles with necessary permissions if you're running Terraform on 
an AWS EC2 instance.
-  - For more information on configuring AWS credentials for Terraform, see the 
[official 
documentation](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#authentication-and-configuration).
-3. A working knowledge of Terraform and AWS resources
-
-## Instructions
-
-### 1. Initialization
-
-Before applying any Terraform script, initialize your Terraform working 
directory:
-
-```bash
-cd aws/
-terraform init
-```
-
-### 2. Configuration
-
-The script is designed with modularity and reusability in mind. Various 
parameters like region, instance count, instance type, etc., are exposed as 
variables for easier customization.
-
-For the full configuration list, please refer to [the doc](/aws/README.md).
-
-To modify the default values, you can create a `terraform.tfvars` file in the 
same directory as your Terraform script:
-
-```bash
-oap_instance_count = 2
-ui_instance_count  = 2
-region             = "us-west-1"
-instance_type      = "t2.large"
-extra_tags         = {
-  "Environment" = "Production"
-}
-```
-
-### 3. Test and apply the outcomes of the Script
-
-After adjusting your configuration, test and apply the script:
-
-```bash
-terraform plan
-terraform apply
-```
-
-After all the resources are created, you can head to the
-[Ansible part](#ansible) to start deploying SkyWalking.
-
-### 4. Accessing the Resources
-
-#### SSH into bastion host (Optional)
-
-You don't usually need to SSH into the bastion host, but if you want to, you 
can
-SSH into the bastion host with the command:
-
-```shell
-KEY_FILE=$(terraform output -raw ssh-user-key-file)
-BASTION_IP=$(terraform output -json bastion_ips | jq -r '.[0]')
-
-ssh -i "$KEY_FILE" ec2-user@"$BASTION_IP"
-```
-
-- **Security Attention**: two security rules are created for the bastion host:
-  - `ssh-access`: Allows SSH access from any IP (`0.0.0.0/0`). **Please note** 
that this is potentially insecure and you should restrict the IP range wherever 
possible.
-  - `public-egress-access`: Allows egress access to the internet for the 
instances.
-
-### 5. Tearing Down
-
-To destroy the resources when they are no longer needed:
-
-```bash
-terraform destroy
-```
+- [AWS](aws): Terraform scripts to provision necessary resources on Amazon Web 
Services.
 
-This command will prompt you to confirm before destroying the resources.
+> [!NOTE]
+> HashiCorp had changed the LICENSE of Terraform from MPL 2.0 to BSL/BUSL 1.1
+> since its 1.5.6 release. We don't have hard-dependencies on Terraform.
+> 
+> OpenTF Foundation announced to maintain the MPL 2.0 based fork of Terraform.
+> Read their [announcement](https://opentf.org/announcement) and
+> [website](https://opentf.org/) for more details.
+> 
+> All Terraform and/or OpenTF scripts are just for end-user convenience.
+> The Apache 2.0 License is only for the scripts.
 
-## Security Note
-
-SSH access is open to the entire internet (`0.0.0.0/0`). This is not 
recommended for production environments. Always restrict the CIDR block to 
known IP ranges for better security.
 
 # Ansible
 
 You can use the Ansible playbook in combination with the Terraform to create 
necessary infrastructure and install
 SkyWalking on the created infrastructure, or you can use the Ansible to 
install SkyWalking on the existing infrastructure.
 
-This guide provides steps on using Ansible to install Apache SkyWalking on AWS 
instances.
-
-## Prerequisites
-
-1. Ansible installed.
-2. A working knowledge of Ansible and AWS resources.
-3. An active SSH key and access to AWS EC2 instances.
-
-## Instructions
-
-### 1. Change diroectory
-
-```shell
-cd ../ansible/
-```
-
-### 2. Test Connectivity to the EC2 Instances
-
-Before installing SkyWalking, ensure that you can connect to the EC2 instances:
-
-```
-ansible -m ping all -u ec2-user
-```
-
-**Expected Output**:
-
-You should see output for each IP with a `SUCCESS` status:
-```text
-<ip1> | SUCCESS => {
-    "ansible_facts": {
-        "discovered_interpreter_python": "/usr/bin/python3"
-    },
-    "changed": false,
-    "ping": "pong"
-}
-<ip2> | SUCCESS => {
-    "ansible_facts": {
-        "discovered_interpreter_python": "/usr/bin/python3"
-    },
-    "changed": false,
-    "ping": "pong"
-}
-```
-
-### 3. Install Apache SkyWalking
-
-After confirming connectivity, proceed to install Apache SkyWalking using the 
Ansible playbook:
-
-```
-ansible-playbook skywalking.yml
-```
-
-### 4. Configurations
-
-The Ansible playbook can be customized to install Apache SkyWalking with
-different configurations. The following variables can be modified to suit your
-needs: 
-
-> For full configurations, refer to the
-> 
[ansible/roles/skywalking/vars/main.yml](ansible/roles/skywalking/vars/main.yml).
-> file.
-
-```yaml
-# `skywalking_tarball` can be a remote URL or a local path, if it's a remote 
URL
-# the remote file will be downloaded to the remote host and then extracted,
-# if it's a local path, the local file will be copied to the remote host and
-# then extracted.
-skywalking_tarball: 
"https://dist.apache.org/repos/dist/release/skywalking/9.5.0/apache-skywalking-apm-9.5.0.tar.gz";
-
-# `skywalking_ui_environment` is a dictionary of environment variables that 
will
-# be sourced when running the skywalking-ui service. All environment variables
-# that are supported by SkyWalking webapp can be set here.
-skywalking_ui_environment: {}
-
-# `skywalking_oap_environment` is a dictionary of environment variables that 
will
-# be sourced when running the skywalking-oap service. All environment variables
-# that are supported by SkyWalking OAP can be set here.
-skywalking_oap_environment: {}
-
-```
-
-### 5. Accessing SkyWalking UI!
-
-After the installation is complete, you can go back to the aws folder and get
-the ALB domain name address that can be used to  access the SkyWalking UI:
-
-```shell
-cd ../aws
-terraform output -raw alb_dns_name
-```
-
-And you can open your browser and access the SkyWalking UI with the address.
-
+Please go to the [ansible](ansible) folder for more details.
diff --git a/ansible/README.md b/ansible/README.md
new file mode 100644
index 0000000..25c7fbf
--- /dev/null
+++ b/ansible/README.md
@@ -0,0 +1,108 @@
+This guide provides steps on using Ansible to install Apache SkyWalking on VM 
instances.
+
+# Prerequisites
+
+- [Ansible 
installed](https://docs.ansible.com/ansible/latest/installation_guide/index.html).
+- A working knowledge of Ansible.
+- Access to instances.
+
+# Instructions
+
+## Change diroectory
+
+```shell
+cd ansible
+```
+
+## Test Connectivity to the Instances
+
+Before installing SkyWalking, ensure that you can connect to the instances:
+
+```shell
+ansible -m ping all
+```
+
+**Expected Output**:
+
+You should see output for each IP with a `SUCCESS` status:
+
+```text
+<ip1> | SUCCESS => {
+    "ansible_facts": {
+        "discovered_interpreter_python": "/usr/bin/python3"
+    },
+    "changed": false,
+    "ping": "pong"
+}
+<ip2> | SUCCESS => {
+    "ansible_facts": {
+        "discovered_interpreter_python": "/usr/bin/python3"
+    },
+    "changed": false,
+    "ping": "pong"
+}
+```
+
+## Install Apache SkyWalking
+
+After confirming connectivity, proceed to install Apache SkyWalking using the 
Ansible playbook:
+
+```
+ansible-playbook skywalking.yml
+```
+
+## Configurations
+
+The Ansible playbook can be customized to install Apache SkyWalking with
+different configurations. The following variables can be modified to suit your
+needs: 
+
+> For full configurations, refer to the
+> [roles/skywalking/vars/main.yml](roles/skywalking/vars/main.yml).
+> file.
+
+```yaml
+# `skywalking_tarball` can be a remote URL or a local path, if it's a remote 
URL
+# the remote file will be downloaded to the remote host and then extracted,
+# if it's a local path, the local file will be copied to the remote host and
+# then extracted.
+skywalking_tarball: 
"https://dist.apache.org/repos/dist/release/skywalking/9.5.0/apache-skywalking-apm-9.5.0.tar.gz";
+
+# `skywalking_ui_environment` is a dictionary of environment variables that 
will
+# be sourced when running the skywalking-ui service. All environment variables
+# that are supported by SkyWalking webapp can be set here.
+skywalking_ui_environment: {}
+
+# `skywalking_oap_environment` is a dictionary of environment variables that 
will
+# be sourced when running the skywalking-oap service. All environment variables
+# that are supported by SkyWalking OAP can be set here.
+skywalking_oap_environment: {}
+
+```
+
+You can create a local variable file to override the default values:
+
+```shell
+cat <<EOF > local.var.yaml
+skywalking_tarball: 
"~/workspace/skywalking/apm-dist/target/apache-skywalking-apm-bin.tar.gz"
+EOF
+```
+
+And then run the playbook with the local variable file:
+
+```shell
+ansible-playbook skywalking.yml -e @local.var.yaml
+```
+
+## Accessing SkyWalking UI!
+
+After the installation is complete, you can go back to the aws folder and get
+the ALB domain name address that can be used to access the SkyWalking UI:
+
+```shell
+cd ../aws
+terraform output -raw alb_dns_name
+```
+
+And you can open your browser and access the SkyWalking UI with the address.
+
diff --git a/aws/README.md b/aws/README.md
index 3d3f3f3..19b0b45 100644
--- a/aws/README.md
+++ b/aws/README.md
@@ -1,84 +1,107 @@
-<!-- BEGIN_TF_DOCS -->
-## Requirements
-
-No requirements.
-
-## Providers
-
-| Name | Version |
-|------|---------|
-| <a name="provider_aws"></a> [aws](#provider\_aws) | 5.10.0 |
-| <a name="provider_local"></a> [local](#provider\_local) | 2.4.0 |
-| <a name="provider_random"></a> [random](#provider\_random) | 3.5.1 |
-| <a name="provider_tls"></a> [tls](#provider\_tls) | 4.0.4 |
-
-## Modules
-
-| Name | Source | Version |
-|------|--------|---------|
-| <a name="module_alb"></a> [alb](#module\_alb) | 
terraform-aws-modules/alb/aws | ~> 8.0 |
-| <a name="module_rds"></a> [rds](#module\_rds) | 
terraform-aws-modules/rds/aws | ~> 5.0 |
-| <a name="module_vpc"></a> [vpc](#module\_vpc) | 
terraform-aws-modules/vpc/aws | ~> 5.0 |
-
-## Resources
-
-| Name | Type |
-|------|------|
-| 
[aws_instance.bastion](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance)
 | resource |
-| 
[aws_instance.skywalking-oap](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance)
 | resource |
-| 
[aws_instance.skywalking-ui](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance)
 | resource |
-| 
[aws_key_pair.ssh-user](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/key_pair)
 | resource |
-| 
[aws_security_group.allow_apps](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group)
 | resource |
-| 
[aws_security_group.bastion](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group)
 | resource |
-| 
[aws_security_group.public-egress-access](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group)
 | resource |
-| 
[aws_security_group.skywalking-oap](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group)
 | resource |
-| 
[aws_security_group.skywalking-ui](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group)
 | resource |
-| 
[local_file.inventories](https://registry.terraform.io/providers/hashicorp/local/latest/docs/resources/file)
 | resource |
-| 
[local_file.ssh-user](https://registry.terraform.io/providers/hashicorp/local/latest/docs/resources/file)
 | resource |
-| 
[random_password.rds_password](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password)
 | resource |
-| 
[tls_private_key.ssh-user](https://registry.terraform.io/providers/hashicorp/tls/latest/docs/resources/private_key)
 | resource |
-| 
[aws_ami.amazon-linux](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ami)
 | data source |
-| 
[aws_availability_zones.available](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/availability_zones)
 | data source |
-
-## Inputs
-
-| Name | Description | Type | Default | Required |
-|------|-------------|------|---------|:--------:|
-| <a name="input_access_key"></a> [access\_key](#input\_access\_key) | Access 
key of the AWS account, if you have configured AWS CLI, you can leave it empty. 
| `string` | `""` | no |
-| <a name="input_bastion_enabled"></a> 
[bastion\_enabled](#input\_bastion\_enabled) | Enable bastion host, if you want 
to access the instances via SSH, you must enable it. | `bool` | `true` | no |
-| <a name="input_bastion_instance_type"></a> 
[bastion\_instance\_type](#input\_bastion\_instance\_type) | CPU, memory, 
storage and networking capacity for bastion host | `string` | `"t2.micro"` | no 
|
-| <a name="input_cidr"></a> [cidr](#input\_cidr) | CIDR for database tier | 
`string` | `"11.0.0.0/16"` | no |
-| <a name="input_cluster_name"></a> [cluster\_name](#input\_cluster\_name) | 
Name of the cluster | `string` | `"skywalking-cluster"` | no |
-| <a name="input_database_subnets"></a> 
[database\_subnets](#input\_database\_subnets) | CIDR used for database subnets 
| `set(string)` | <pre>[<br>  "11.0.104.0/24",<br>  "11.0.105.0/24",<br>  
"11.0.106.0/24"<br>]</pre> | no |
-| <a name="input_db_instance_class"></a> 
[db\_instance\_class](#input\_db\_instance\_class) | Instance class for the 
database | `string` | `"db.t3.medium"` | no |
-| <a name="input_db_max_storage_size"></a> 
[db\_max\_storage\_size](#input\_db\_max\_storage\_size) | Maximum storage size 
for the database, in GB | `number` | `100` | no |
-| <a name="input_db_name"></a> [db\_name](#input\_db\_name) | Name of the 
database | `string` | `"skywalking"` | no |
-| <a name="input_db_password"></a> [db\_password](#input\_db\_password) | 
Password for the database, if not set, a random password will be generated. | 
`string` | `null` | no |
-| <a name="input_db_storage_size"></a> 
[db\_storage\_size](#input\_db\_storage\_size) | Storage size for the database, 
in GB | `number` | `5` | no |
-| <a name="input_db_username"></a> [db\_username](#input\_db\_username) | 
Username for the database | `string` | `"skywalking"` | no |
-| <a name="input_extra_tags"></a> [extra\_tags](#input\_extra\_tags) | 
Additional tags to be added to all resources | `map(string)` | `{}` | no |
-| <a name="input_instance_type"></a> [instance\_type](#input\_instance\_type) 
| CPU, memory, storage and networking capacity for OAP and UI instances | 
`string` | `"t2.medium"` | no |
-| <a name="input_oap_instance_count"></a> 
[oap\_instance\_count](#input\_oap\_instance\_count) | Number of OAP instances, 
if you want to use H2 storage, you must set it to 1. | `number` | `1` | no |
-| <a name="input_private_subnets"></a> 
[private\_subnets](#input\_private\_subnets) | CIDR used for private subnets | 
`set(string)` | <pre>[<br>  "11.0.1.0/24",<br>  "11.0.2.0/24",<br>  
"11.0.3.0/24"<br>]</pre> | no |
-| <a name="input_public_key_path"></a> 
[public\_key\_path](#input\_public\_key\_path) | Path to store the key file for 
SSH access to the instances. | `string` | `"~/.ssh"` | no |
-| <a name="input_public_subnets"></a> 
[public\_subnets](#input\_public\_subnets) | CIDR used for public subnets | 
`set(string)` | <pre>[<br>  "11.0.101.0/24",<br>  "11.0.102.0/24",<br>  
"11.0.103.0/24"<br>]</pre> | no |
-| <a name="input_region"></a> [region](#input\_region) | Physical location for 
clustered data centers. | `string` | `"us-east-1"` | no |
-| <a name="input_secret_key"></a> [secret\_key](#input\_secret\_key) | Secret 
key of the AWS account, if you have configured AWS CLI, you can leave it empty. 
| `string` | `""` | no |
-| <a name="input_storage"></a> [storage](#input\_storage) | Storage type for 
SkyWalking OAP, can be 'h2', or 'rds-postgresql' | `string` | 
`"rds-postgresql"` | no |
-| <a name="input_ui_instance_count"></a> 
[ui\_instance\_count](#input\_ui\_instance\_count) | Number of UI instances | 
`number` | `1` | no |
-
-## Outputs
-
-| Name | Description |
-|------|-------------|
-| <a name="output_alb_dns_name"></a> [alb\_dns\_name](#output\_alb\_dns\_name) 
| The domain name of the ALB that can be used to access SkyWalking UI. |
-| <a name="output_bastion_ips"></a> [bastion\_ips](#output\_bastion\_ips) | 
The public IP that can be used to SSH into the bastion host. |
-| <a name="output_database_address"></a> 
[database\_address](#output\_database\_address) | The database address |
-| <a name="output_database_name"></a> 
[database\_name](#output\_database\_name) | The database name |
-| <a name="output_database_password"></a> 
[database\_password](#output\_database\_password) | The database password |
-| <a name="output_database_port"></a> 
[database\_port](#output\_database\_port) | The database port |
-| <a name="output_database_username"></a> 
[database\_username](#output\_database\_username) | The database username |
-| <a name="output_skywalking_oap_ips"></a> 
[skywalking\_oap\_ips](#output\_skywalking\_oap\_ips) | The private IPs of the 
OAP instances |
-| <a name="output_skywalking_ui_ips"></a> 
[skywalking\_ui\_ips](#output\_skywalking\_ui\_ips) | The IPs of the SkyWalking 
UI instances |
-| <a name="output_ssh-user-key-file"></a> 
[ssh-user-key-file](#output\_ssh-user-key-file) | The SSH key file that can be 
used to connect to the bastion instance. |
-<!-- END_TF_DOCS -->
\ No newline at end of file
+# Prerequisites
+
+- [Terraform installed](https://developer.hashicorp.com/terraform/downloads).
+- AWS Credentials: Ensure your environment is set up with the necessary AWS 
credentials. This can be done in various ways, such as:
+  - Setting the `access_key` and `secret_key` variable in Terraform.
+  - Setting up environment variables (`AWS_ACCESS_KEY_ID` and 
`AWS_SECRET_ACCESS_KEY`).
+  - Configuring using the [AWS 
CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html).
+  - Using IAM roles with necessary permissions if you're running Terraform on 
an AWS EC2 instance.
+  - For more information on configuring AWS credentials for Terraform, see the 
[official 
documentation](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#authentication-and-configuration).
+- A working knowledge of Terraform and AWS resources
+
+# Instructions
+
+## Initialization
+
+Before applying any Terraform script, initialize your Terraform working 
directory:
+
+```bash
+terraform init
+```
+
+## Configuration
+
+The script is designed with modularity and reusability in mind. Various 
+parameters like region, instance count, instance type, etc., are exposed
+as variables for easier customization.
+
+For the full configuration list, please refer to [the doc](configurations.md).
+
+To modify the default values, you can create a `terraform.tfvars` file in the
+same directory as your Terraform script:
+
+```bash
+cat <<EOF > terraform.tfvars
+region     = "ap-southeast-1"
+access_key = "<access_key>"
+secret_key = "<secret_key>"
+storage    = "rds-postgresql"
+extra_tags         = {
+  "Environment" = "Production"
+}
+EOF
+```
+
+## Test and apply the outcomes of the script
+
+After adjusting your configuration, test and apply the script:
+
+```bash
+terraform plan
+terraform apply
+```
+
+> [!WARNING]
+> **Security Attention**: two security rules are created for the bastion host:
+>  - `ssh-access`: Allows SSH access from any IP (`0.0.0.0/0`).
+>    **Please note** that this is potentially insecure and you should restrict
+>    the IP range by setting the variable `bastion_ssh_cidr_blocks`.
+>  - `public-egress-access`: Allows egress access to the internet for the 
instances.
+
+After all the resources are created, you can head to the
+[Ansible part](../ansible/README.md) to start deploying SkyWalking.
+
+## Accessing the resources
+
+### SSH into bastion host (Optional)
+
+You don't usually need to directly SSH into the bastion host, but if you want,
+you can SSH into the bastion host with the command:
+
+```shell
+KEY_FILE=$(terraform output -raw ssh_user_key_file)
+BASTION_IP=$(terraform output -json bastion_ips | jq -r '.[0]')
+
+ssh -i "$KEY_FILE" ec2-user@"$BASTION_IP"
+```
+
+### Access the SkyWalking UI ALB
+
+If you set the variable `create_lb` to `true` (this is set by default, so if 
you
+didn't set it to `false`, you should have an ALB), you can access the 
SkyWalking
+UI ALB with the command:
+
+```shell
+terraform output -raw alb_dns_name
+```
+
+When you open the URL in your browser, you should see something like this:
+
+```text
+503 Service Temporarily Unavailable
+```
+
+This is because you didn't deploy SkyWalking yet, after you complete the steps
+in the [Ansible part](../ansible/README.md), you should be able to see the
+SkyWalking UI then.
+
+## Tearing Down
+
+To destroy the resources when they are no longer needed:
+
+```bash
+terraform destroy
+```
+
+This command will prompt you to confirm before destroying the resources.
+
diff --git a/aws/alb-main.tf b/aws/alb-main.tf
index a1cfc28..83d1dcf 100644
--- a/aws/alb-main.tf
+++ b/aws/alb-main.tf
@@ -17,6 +17,8 @@ module "alb" {
   source  = "terraform-aws-modules/alb/aws"
   version = "~> 8.0"
 
+  create_lb = var.create_lb
+
   name = var.cluster_name
 
   load_balancer_type = "application"
@@ -50,8 +52,8 @@ module "alb" {
       backend_port     = 8080
       target_type      = "instance"
       targets = [
-        for i, ui in aws_instance.skywalking-ui : {
-          target_id = ui.id
+        for i, ui_id in module.skywalking.ui_instance_ids : {
+          target_id = ui_id
           port      = 8080
         }
       ]
@@ -68,3 +70,19 @@ module "alb" {
 
   tags = var.extra_tags
 }
+
+resource "aws_security_group" "alb-skywalking-ui" {
+  count = var.create_lb ? 1 : 0
+
+  name        = "alb-skywalking-ui"
+  description = "Security group for ALB to access SkyWalking UI"
+  vpc_id      = module.vpc.vpc_id
+
+  ingress {
+    from_port       = 8080
+    to_port         = 8080
+    protocol        = "tcp"
+    description     = "Allow access from ALB to SkyWalking UI"
+    security_groups = [module.alb.security_group_id]
+  }
+}
diff --git a/aws/README.md b/aws/configurations.md
similarity index 74%
copy from aws/README.md
copy to aws/configurations.md
index 3d3f3f3..a91a72f 100644
--- a/aws/README.md
+++ b/aws/configurations.md
@@ -10,7 +10,6 @@ No requirements.
 | <a name="provider_aws"></a> [aws](#provider\_aws) | 5.10.0 |
 | <a name="provider_local"></a> [local](#provider\_local) | 2.4.0 |
 | <a name="provider_random"></a> [random](#provider\_random) | 3.5.1 |
-| <a name="provider_tls"></a> [tls](#provider\_tls) | 4.0.4 |
 
 ## Modules
 
@@ -18,26 +17,18 @@ No requirements.
 |------|--------|---------|
 | <a name="module_alb"></a> [alb](#module\_alb) | 
terraform-aws-modules/alb/aws | ~> 8.0 |
 | <a name="module_rds"></a> [rds](#module\_rds) | 
terraform-aws-modules/rds/aws | ~> 5.0 |
+| <a name="module_skywalking"></a> [skywalking](#module\_skywalking) | 
./modules/skywalking | n/a |
 | <a name="module_vpc"></a> [vpc](#module\_vpc) | 
terraform-aws-modules/vpc/aws | ~> 5.0 |
 
 ## Resources
 
 | Name | Type |
 |------|------|
-| 
[aws_instance.bastion](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance)
 | resource |
-| 
[aws_instance.skywalking-oap](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance)
 | resource |
-| 
[aws_instance.skywalking-ui](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance)
 | resource |
-| 
[aws_key_pair.ssh-user](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/key_pair)
 | resource |
+| 
[aws_security_group.alb-skywalking-ui](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group)
 | resource |
 | 
[aws_security_group.allow_apps](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group)
 | resource |
-| 
[aws_security_group.bastion](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group)
 | resource |
 | 
[aws_security_group.public-egress-access](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group)
 | resource |
-| 
[aws_security_group.skywalking-oap](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group)
 | resource |
-| 
[aws_security_group.skywalking-ui](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group)
 | resource |
 | 
[local_file.inventories](https://registry.terraform.io/providers/hashicorp/local/latest/docs/resources/file)
 | resource |
-| 
[local_file.ssh-user](https://registry.terraform.io/providers/hashicorp/local/latest/docs/resources/file)
 | resource |
 | 
[random_password.rds_password](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password)
 | resource |
-| 
[tls_private_key.ssh-user](https://registry.terraform.io/providers/hashicorp/tls/latest/docs/resources/private_key)
 | resource |
-| 
[aws_ami.amazon-linux](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ami)
 | data source |
 | 
[aws_availability_zones.available](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/availability_zones)
 | data source |
 
 ## Inputs
@@ -49,6 +40,7 @@ No requirements.
 | <a name="input_bastion_instance_type"></a> 
[bastion\_instance\_type](#input\_bastion\_instance\_type) | CPU, memory, 
storage and networking capacity for bastion host | `string` | `"t2.micro"` | no 
|
 | <a name="input_cidr"></a> [cidr](#input\_cidr) | CIDR for database tier | 
`string` | `"11.0.0.0/16"` | no |
 | <a name="input_cluster_name"></a> [cluster\_name](#input\_cluster\_name) | 
Name of the cluster | `string` | `"skywalking-cluster"` | no |
+| <a name="input_create_lb"></a> [create\_lb](#input\_create\_lb) | Create 
load balancer for SkyWalking UI | `bool` | `true` | no |
 | <a name="input_database_subnets"></a> 
[database\_subnets](#input\_database\_subnets) | CIDR used for database subnets 
| `set(string)` | <pre>[<br>  "11.0.104.0/24",<br>  "11.0.105.0/24",<br>  
"11.0.106.0/24"<br>]</pre> | no |
 | <a name="input_db_instance_class"></a> 
[db\_instance\_class](#input\_db\_instance\_class) | Instance class for the 
database | `string` | `"db.t3.medium"` | no |
 | <a name="input_db_max_storage_size"></a> 
[db\_max\_storage\_size](#input\_db\_max\_storage\_size) | Maximum storage size 
for the database, in GB | `number` | `100` | no |
@@ -57,8 +49,8 @@ No requirements.
 | <a name="input_db_storage_size"></a> 
[db\_storage\_size](#input\_db\_storage\_size) | Storage size for the database, 
in GB | `number` | `5` | no |
 | <a name="input_db_username"></a> [db\_username](#input\_db\_username) | 
Username for the database | `string` | `"skywalking"` | no |
 | <a name="input_extra_tags"></a> [extra\_tags](#input\_extra\_tags) | 
Additional tags to be added to all resources | `map(string)` | `{}` | no |
-| <a name="input_instance_type"></a> [instance\_type](#input\_instance\_type) 
| CPU, memory, storage and networking capacity for OAP and UI instances | 
`string` | `"t2.medium"` | no |
 | <a name="input_oap_instance_count"></a> 
[oap\_instance\_count](#input\_oap\_instance\_count) | Number of OAP instances, 
if you want to use H2 storage, you must set it to 1. | `number` | `1` | no |
+| <a name="input_oap_instance_type"></a> 
[oap\_instance\_type](#input\_oap\_instance\_type) | CPU, memory, storage and 
networking capacity for OAP instances | `string` | `"c5.xlarge"` | no |
 | <a name="input_private_subnets"></a> 
[private\_subnets](#input\_private\_subnets) | CIDR used for private subnets | 
`set(string)` | <pre>[<br>  "11.0.1.0/24",<br>  "11.0.2.0/24",<br>  
"11.0.3.0/24"<br>]</pre> | no |
 | <a name="input_public_key_path"></a> 
[public\_key\_path](#input\_public\_key\_path) | Path to store the key file for 
SSH access to the instances. | `string` | `"~/.ssh"` | no |
 | <a name="input_public_subnets"></a> 
[public\_subnets](#input\_public\_subnets) | CIDR used for public subnets | 
`set(string)` | <pre>[<br>  "11.0.101.0/24",<br>  "11.0.102.0/24",<br>  
"11.0.103.0/24"<br>]</pre> | no |
@@ -66,19 +58,19 @@ No requirements.
 | <a name="input_secret_key"></a> [secret\_key](#input\_secret\_key) | Secret 
key of the AWS account, if you have configured AWS CLI, you can leave it empty. 
| `string` | `""` | no |
 | <a name="input_storage"></a> [storage](#input\_storage) | Storage type for 
SkyWalking OAP, can be 'h2', or 'rds-postgresql' | `string` | 
`"rds-postgresql"` | no |
 | <a name="input_ui_instance_count"></a> 
[ui\_instance\_count](#input\_ui\_instance\_count) | Number of UI instances | 
`number` | `1` | no |
+| <a name="input_ui_instance_type"></a> 
[ui\_instance\_type](#input\_ui\_instance\_type) | CPU, memory, storage and 
networking capacity for UI instances | `string` | `"t2.medium"` | no |
 
 ## Outputs
 
 | Name | Description |
 |------|-------------|
 | <a name="output_alb_dns_name"></a> [alb\_dns\_name](#output\_alb\_dns\_name) 
| The domain name of the ALB that can be used to access SkyWalking UI. |
-| <a name="output_bastion_ips"></a> [bastion\_ips](#output\_bastion\_ips) | 
The public IP that can be used to SSH into the bastion host. |
+| <a name="output_bastion_ips"></a> [bastion\_ips](#output\_bastion\_ips) | 
The public IP that can be used to SSH into the bastion host |
 | <a name="output_database_address"></a> 
[database\_address](#output\_database\_address) | The database address |
 | <a name="output_database_name"></a> 
[database\_name](#output\_database\_name) | The database name |
 | <a name="output_database_password"></a> 
[database\_password](#output\_database\_password) | The database password |
 | <a name="output_database_port"></a> 
[database\_port](#output\_database\_port) | The database port |
 | <a name="output_database_username"></a> 
[database\_username](#output\_database\_username) | The database username |
-| <a name="output_skywalking_oap_ips"></a> 
[skywalking\_oap\_ips](#output\_skywalking\_oap\_ips) | The private IPs of the 
OAP instances |
-| <a name="output_skywalking_ui_ips"></a> 
[skywalking\_ui\_ips](#output\_skywalking\_ui\_ips) | The IPs of the SkyWalking 
UI instances |
-| <a name="output_ssh-user-key-file"></a> 
[ssh-user-key-file](#output\_ssh-user-key-file) | The SSH key file that can be 
used to connect to the bastion instance. |
+| <a name="output_oap_ips"></a> [oap\_ips](#output\_oap\_ips) | The private 
IPs of the OAP instances |
+| <a name="output_ui_ips"></a> [ui\_ips](#output\_ui\_ips) | The IPs of the 
SkyWalking UI instances |
 <!-- END_TF_DOCS -->
\ No newline at end of file
diff --git a/aws/ec2-main.tf b/aws/ec2-main.tf
index 6d7dab1..50d27c6 100644
--- a/aws/ec2-main.tf
+++ b/aws/ec2-main.tf
@@ -34,10 +34,10 @@ resource "local_file" "inventories" {
   filename        = "${path.module}/../ansible/inventory/skywalking.yaml"
   file_permission = "0600"
   content = 
templatefile("${path.module}/../ansible/template/inventory.yaml.tftpl", {
-    bastion           = aws_instance.bastion[0]
-    oap_instances     = aws_instance.skywalking-oap
-    ui_instances      = aws_instance.skywalking-ui
-    private_key_file  = local_file.ssh-user.filename
+    bastion           = module.skywalking.bastion_instances[0]
+    oap_instances     = module.skywalking.oap_instances
+    ui_instances      = module.skywalking.ui_instances
+    private_key_file  = module.skywalking.ssh_user_key_file
     database_type     = var.storage
     database_host     = var.storage == "rds-postgresql" ? 
module.rds[0].db_instance_address : ""
     database_port     = var.storage == "rds-postgresql" ? 
module.rds[0].db_instance_port : ""
diff --git a/aws/key-pair-output.tf b/aws/key-pair-output.tf
deleted file mode 100644
index a1a4271..0000000
--- a/aws/key-pair-output.tf
+++ /dev/null
@@ -1,21 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-output "ssh-user-key-file" {
-  value       = local_file.ssh-user.filename
-  description = "The SSH key file that can be used to connect to the bastion 
instance."
-}
diff --git a/aws/modules/skywalking/README.md b/aws/modules/skywalking/README.md
new file mode 100644
index 0000000..62a69ab
--- /dev/null
+++ b/aws/modules/skywalking/README.md
@@ -0,0 +1,72 @@
+<!-- BEGIN_TF_DOCS -->
+## Requirements
+
+No requirements.
+
+## Providers
+
+| Name | Version |
+|------|---------|
+| <a name="provider_aws"></a> [aws](#provider\_aws) | n/a |
+| <a name="provider_local"></a> [local](#provider\_local) | n/a |
+| <a name="provider_tls"></a> [tls](#provider\_tls) | n/a |
+
+## Modules
+
+No modules.
+
+## Resources
+
+| Name | Type |
+|------|------|
+| 
[aws_instance.bastion](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance)
 | resource |
+| 
[aws_instance.skywalking-oap](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance)
 | resource |
+| 
[aws_instance.skywalking-ui](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance)
 | resource |
+| 
[aws_key_pair.ssh-user](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/key_pair)
 | resource |
+| 
[aws_security_group.bastion](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group)
 | resource |
+| 
[aws_security_group.skywalking-oap](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group)
 | resource |
+| 
[aws_security_group.skywalking-ui](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group)
 | resource |
+| 
[local_file.ssh-user](https://registry.terraform.io/providers/hashicorp/local/latest/docs/resources/file)
 | resource |
+| 
[tls_private_key.ssh-user](https://registry.terraform.io/providers/hashicorp/tls/latest/docs/resources/private_key)
 | resource |
+| 
[aws_ami.amazon-linux](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ami)
 | data source |
+
+## Inputs
+
+| Name | Description | Type | Default | Required |
+|------|-------------|------|---------|:--------:|
+| <a name="input_bastion_enabled"></a> 
[bastion\_enabled](#input\_bastion\_enabled) | Enable bastion host, if you want 
to access the instances via SSH, you must enable it. | `bool` | `true` | no |
+| <a name="input_bastion_instance_type"></a> 
[bastion\_instance\_type](#input\_bastion\_instance\_type) | CPU, memory, 
storage and networking capacity for bastion host | `string` | `"t2.micro"` | no 
|
+| <a name="input_cluster_name"></a> [cluster\_name](#input\_cluster\_name) | 
Name of the cluster | `string` | `"skywalking-cluster"` | no |
+| <a name="input_create_lb"></a> [create\_lb](#input\_create\_lb) | Create a 
load balancer for UI instances | `bool` | `true` | no |
+| <a name="input_extra_tags"></a> [extra\_tags](#input\_extra\_tags) | 
Additional tags to be added to all resources | `map(string)` | `{}` | no |
+| <a name="input_oap_instance_ami_id"></a> 
[oap\_instance\_ami\_id](#input\_oap\_instance\_ami\_id) | AMI ID for OAP 
instances, if not set, a suitable AMI ID will be selected automatically. | 
`string` | `""` | no |
+| <a name="input_oap_instance_count"></a> 
[oap\_instance\_count](#input\_oap\_instance\_count) | Number of OAP instances, 
if you want to use H2 storage, you must set it to 1. | `number` | `1` | no |
+| <a name="input_oap_instance_security_group_ids"></a> 
[oap\_instance\_security\_group\_ids](#input\_oap\_instance\_security\_group\_ids)
 | Additional security groups for OAP instances | `list(string)` | `[]` | no |
+| <a name="input_oap_instance_subnet_id"></a> 
[oap\_instance\_subnet\_id](#input\_oap\_instance\_subnet\_id) | Subnet ID for 
OAP instances | `string` | n/a | yes |
+| <a name="input_oap_instance_type"></a> 
[oap\_instance\_type](#input\_oap\_instance\_type) | CPU, memory, storage and 
networking capacity for OAP instances | `string` | `"c5.xlarge"` | no |
+| <a name="input_public_key_path"></a> 
[public\_key\_path](#input\_public\_key\_path) | Path to store the key file for 
SSH access to the instances. | `string` | `"~/.ssh"` | no |
+| <a name="input_storage"></a> [storage](#input\_storage) | Storage type for 
SkyWalking OAP, can be `h2`, or `rds-postgresql` | `string` | 
`"rds-postgresql"` | no |
+| <a name="input_ui_instance_ami_id"></a> 
[ui\_instance\_ami\_id](#input\_ui\_instance\_ami\_id) | AMI ID for UI 
instances, if not set, a suitable AMI ID will be selected automatically. | 
`string` | `""` | no |
+| <a name="input_ui_instance_count"></a> 
[ui\_instance\_count](#input\_ui\_instance\_count) | Number of UI instances | 
`number` | `1` | no |
+| <a name="input_ui_instance_security_group_ids"></a> 
[ui\_instance\_security\_group\_ids](#input\_ui\_instance\_security\_group\_ids)
 | Additional security groups for UI instances | `list(string)` | `[]` | no |
+| <a name="input_ui_instance_subnet_id"></a> 
[ui\_instance\_subnet\_id](#input\_ui\_instance\_subnet\_id) | Subnet ID for UI 
instances | `string` | n/a | yes |
+| <a name="input_ui_instance_type"></a> 
[ui\_instance\_type](#input\_ui\_instance\_type) | CPU, memory, storage and 
networking capacity for UI instances | `string` | `"t2.medium"` | no |
+| <a name="input_vpc_bastion_subnet_id"></a> 
[vpc\_bastion\_subnet\_id](#input\_vpc\_bastion\_subnet\_id) | Subnet ID for 
bastion host | `string` | n/a | yes |
+| <a name="input_vpc_id"></a> [vpc\_id](#input\_vpc\_id) | VPC ID | `string` | 
n/a | yes |
+
+## Outputs
+
+| Name | Description |
+|------|-------------|
+| <a name="output_bastion_instances"></a> 
[bastion\_instances](#output\_bastion\_instances) | The bastion instances |
+| <a name="output_bastion_ips"></a> [bastion\_ips](#output\_bastion\_ips) | 
The public IP that can be used to SSH into the bastion host |
+| <a name="output_oap_instance_ids"></a> 
[oap\_instance\_ids](#output\_oap\_instance\_ids) | The IDs of the OAP 
instances |
+| <a name="output_oap_instances"></a> 
[oap\_instances](#output\_oap\_instances) | The OAP instances |
+| <a name="output_oap_ips"></a> [oap\_ips](#output\_oap\_ips) | The private 
IPs of the OAP instances |
+| <a name="output_oap_security_groups"></a> 
[oap\_security\_groups](#output\_oap\_security\_groups) | The security groups 
of the OAP instances |
+| <a name="output_ssh_user_key_file"></a> 
[ssh\_user\_key\_file](#output\_ssh\_user\_key\_file) | The SSH key file that 
can be used to connect to the bastion instance. |
+| <a name="output_ui_instance_ids"></a> 
[ui\_instance\_ids](#output\_ui\_instance\_ids) | The IDs of the SkyWalking UI 
instances |
+| <a name="output_ui_instances"></a> [ui\_instances](#output\_ui\_instances) | 
The SkyWalking UI instances |
+| <a name="output_ui_ips"></a> [ui\_ips](#output\_ui\_ips) | The IPs of the 
SkyWalking UI instances |
+| <a name="output_ui_security_groups"></a> 
[ui\_security\_groups](#output\_ui\_security\_groups) | The security groups of 
the SkyWalking UI instances |
+<!-- END_TF_DOCS -->
\ No newline at end of file
diff --git a/aws/bastion-main.tf b/aws/modules/skywalking/main-bastion.tf
similarity index 87%
rename from aws/bastion-main.tf
rename to aws/modules/skywalking/main-bastion.tf
index 6ddb9df..1c892ec 100644
--- a/aws/bastion-main.tf
+++ b/aws/modules/skywalking/main-bastion.tf
@@ -18,13 +18,10 @@ resource "aws_instance" "bastion" {
   ami                         = data.aws_ami.amazon-linux.id
   instance_type               = var.bastion_instance_type
   key_name                    = aws_key_pair.ssh-user.id
-  subnet_id                   = element(module.vpc.public_subnets, 0)
+  subnet_id                   = var.vpc_bastion_subnet_id
   associate_public_ip_address = true
 
-  vpc_security_group_ids = [
-    aws_security_group.bastion.id,
-    aws_security_group.public-egress-access.id
-  ]
+  vpc_security_group_ids = [aws_security_group.bastion.id]
   tags = merge(
     {
       Name        = "Bastion Host"
@@ -54,13 +51,20 @@ resource "aws_instance" "bastion" {
 resource "aws_security_group" "bastion" {
   name        = "bastion"
   description = "Security group for bastion"
-  vpc_id      = module.vpc.vpc_id
+  vpc_id      = var.vpc_id
 
   ingress {
     description = "SSH access from the Internet"
     from_port   = 22
     to_port     = 22
     protocol    = "tcp"
+    cidr_blocks = var.bastion_ssh_cidr_blocks
+  }
+
+  egress {
+    from_port   = 0
+    to_port     = 0
+    protocol    = "-1"
     cidr_blocks = ["0.0.0.0/0"]
   }
 
diff --git a/aws/system-main.tf b/aws/modules/skywalking/main-data.tf
similarity index 100%
rename from aws/system-main.tf
rename to aws/modules/skywalking/main-data.tf
diff --git a/aws/key-pair-main.tf b/aws/modules/skywalking/main-key-pair.tf
similarity index 100%
rename from aws/key-pair-main.tf
rename to aws/modules/skywalking/main-key-pair.tf
diff --git a/aws/skywalking-oap-main.tf b/aws/modules/skywalking/main-oap.tf
similarity index 80%
rename from aws/skywalking-oap-main.tf
rename to aws/modules/skywalking/main-oap.tf
index 3d25f06..1e7e6e2 100644
--- a/aws/skywalking-oap-main.tf
+++ b/aws/modules/skywalking/main-oap.tf
@@ -13,17 +13,22 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+locals {
+  oap_ami_id = var.oap_instance_ami_id != "" ? var.oap_instance_ami_id : 
data.aws_ami.amazon-linux.id
+}
+
 resource "aws_instance" "skywalking-oap" {
   count         = var.oap_instance_count
-  ami           = data.aws_ami.amazon-linux.id
-  instance_type = var.instance_type
+  ami           = local.oap_ami_id
+  instance_type = var.oap_instance_type
   key_name      = aws_key_pair.ssh-user.id
-  subnet_id     = element(module.vpc.private_subnets, 0)
+  subnet_id     = var.oap_instance_subnet_id
+
+  vpc_security_group_ids = concat(
+    var.oap_instance_security_group_ids,
+    [aws_security_group.skywalking-oap.id]
+  )
 
-  vpc_security_group_ids = [
-    aws_security_group.skywalking-oap.id,
-    aws_security_group.public-egress-access.id
-  ]
   tags = merge(
     {
       Name        = "skywalking-oap"
@@ -43,7 +48,7 @@ resource "aws_instance" "skywalking-oap" {
 resource "aws_security_group" "skywalking-oap" {
   name        = "skywalking-oap"
   description = "Security group for SkyWalking OAP"
-  vpc_id      = module.vpc.vpc_id
+  vpc_id      = var.vpc_id
 
   ingress {
     from_port       = 12800
@@ -67,6 +72,13 @@ resource "aws_security_group" "skywalking-oap" {
     security_groups = [aws_security_group.bastion.id]
   }
 
+  egress {
+    from_port   = 0
+    to_port     = 0
+    protocol    = "-1"
+    cidr_blocks = ["0.0.0.0/0"]
+  }
+
   tags = var.extra_tags
 }
 
diff --git a/aws/skywalking-ui-main.tf b/aws/modules/skywalking/main-ui.tf
similarity index 73%
rename from aws/skywalking-ui-main.tf
rename to aws/modules/skywalking/main-ui.tf
index e367159..e2c2e91 100644
--- a/aws/skywalking-ui-main.tf
+++ b/aws/modules/skywalking/main-ui.tf
@@ -13,17 +13,22 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+locals {
+  ui_ami_id = var.ui_instance_ami_id != "" ? var.ui_instance_ami_id : 
data.aws_ami.amazon-linux.id
+}
+
 resource "aws_instance" "skywalking-ui" {
   count         = var.ui_instance_count
-  ami           = data.aws_ami.amazon-linux.id
-  instance_type = var.instance_type
+  ami           = local.ui_ami_id
+  instance_type = var.ui_instance_type
   key_name      = aws_key_pair.ssh-user.id
-  subnet_id     = element(module.vpc.private_subnets, 0)
+  subnet_id     = var.ui_instance_subnet_id
+
+  vpc_security_group_ids = concat(
+    var.ui_instance_security_group_ids,
+    [aws_security_group.skywalking-ui.id]
+  )
 
-  vpc_security_group_ids = [
-    aws_security_group.skywalking-ui.id,
-    aws_security_group.public-egress-access.id
-  ]
   tags = merge(
     {
       Name        = "skywalking-ui"
@@ -36,15 +41,7 @@ resource "aws_instance" "skywalking-ui" {
 resource "aws_security_group" "skywalking-ui" {
   name        = "skywalking-ui"
   description = "Security group for SkyWalking UI"
-  vpc_id      = module.vpc.vpc_id
-
-  ingress {
-    from_port       = 8080
-    to_port         = 8080
-    protocol        = "tcp"
-    description     = "Allow access from ALB to SkyWalking UI"
-    security_groups = [module.alb.security_group_id]
-  }
+  vpc_id      = var.vpc_id
 
   ingress {
     from_port       = 22
@@ -54,6 +51,14 @@ resource "aws_security_group" "skywalking-ui" {
     security_groups = [aws_security_group.bastion.id]
   }
 
+  egress {
+    from_port   = 0
+    to_port     = 0
+    protocol    = "-1"
+    cidr_blocks = ["0.0.0.0/0"]
+    description = "Allow all outbound traffic"
+  }
+
   tags = var.extra_tags
 }
 
diff --git a/aws/modules/skywalking/outputs.tf 
b/aws/modules/skywalking/outputs.tf
new file mode 100644
index 0000000..daf597f
--- /dev/null
+++ b/aws/modules/skywalking/outputs.tf
@@ -0,0 +1,72 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+output "ui_instances" {
+  value       = aws_instance.skywalking-ui
+  description = "The SkyWalking UI instances"
+}
+
+output "ui_instance_ids" {
+  value       = aws_instance.skywalking-ui.*.id
+  description = "The IDs of the SkyWalking UI instances"
+}
+
+output "ui_ips" {
+  value       = aws_instance.skywalking-ui.*.private_ip
+  description = "The IPs of the SkyWalking UI instances"
+}
+
+output "ui_security_groups" {
+  value       = [aws_security_group.skywalking-ui.id]
+  description = "The security groups of the SkyWalking UI instances"
+}
+
+output "oap_instances" {
+  value       = aws_instance.skywalking-oap
+  description = "The OAP instances"
+}
+
+output "oap_instance_ids" {
+  value       = aws_instance.skywalking-oap.*.id
+  description = "The IDs of the OAP instances"
+}
+
+output "oap_ips" {
+  value       = aws_instance.skywalking-oap.*.private_ip
+  description = "The private IPs of the OAP instances"
+}
+
+output "oap_security_groups" {
+  value       = [aws_security_group.skywalking-oap.id]
+  description = "The security groups of the OAP instances"
+}
+
+output "bastion_instances" {
+  value       = aws_instance.bastion
+  description = "The bastion instances"
+}
+
+output "bastion_ips" {
+  value       = aws_instance.bastion.*.public_ip
+  description = "The public IP that can be used to SSH into the bastion host"
+}
+
+output "ssh_user_key_file" {
+  value       = local_file.ssh-user.filename
+  description = "The SSH key file that can be used to connect to the bastion 
instance."
+}
+
diff --git a/aws/variables.tf b/aws/modules/skywalking/variables.tf
similarity index 57%
copy from aws/variables.tf
copy to aws/modules/skywalking/variables.tf
index dfdf1d6..6e8818e 100644
--- a/aws/variables.tf
+++ b/aws/modules/skywalking/variables.tf
@@ -13,22 +13,14 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-variable "region" {
+variable "vpc_id" {
   type        = string
-  description = "Physical location for clustered data centers."
-  default     = "us-east-1"
+  description = "VPC ID"
 }
 
-variable "access_key" {
+variable "vpc_bastion_subnet_id" {
   type        = string
-  description = "Access key of the AWS account, if you have configured AWS 
CLI, you can leave it empty."
-  default     = ""
-}
-
-variable "secret_key" {
-  type        = string
-  description = "Secret key of the AWS account, if you have configured AWS 
CLI, you can leave it empty."
-  default     = ""
+  description = "Subnet ID for bastion host"
 }
 
 variable "cluster_name" {
@@ -43,12 +35,46 @@ variable "oap_instance_count" {
   default     = 1
 }
 
+variable "oap_instance_ami_id" {
+  type        = string
+  description = "AMI ID for OAP instances, if not set, a suitable AMI ID will 
be selected automatically."
+  default     = ""
+}
+
+variable "oap_instance_subnet_id" {
+  type        = string
+  description = "Subnet ID for OAP instances"
+}
+
+variable "oap_instance_security_group_ids" {
+  type        = list(string)
+  description = "Additional security groups for OAP instances"
+  default     = []
+}
+
 variable "ui_instance_count" {
   type        = number
   description = "Number of UI instances"
   default     = 1
 }
 
+variable "ui_instance_ami_id" {
+  type        = string
+  description = "AMI ID for UI instances, if not set, a suitable AMI ID will 
be selected automatically."
+  default     = ""
+}
+
+variable "ui_instance_subnet_id" {
+  type        = string
+  description = "Subnet ID for UI instances"
+}
+
+variable "ui_instance_security_group_ids" {
+  type        = list(string)
+  description = "Additional security groups for UI instances"
+  default     = []
+}
+
 variable "bastion_enabled" {
   type        = bool
   description = "Enable bastion host, if you want to access the instances via 
SSH, you must enable it."
@@ -61,9 +87,21 @@ variable "bastion_instance_type" {
   default     = "t2.micro"
 }
 
-variable "instance_type" {
+variable "bastion_ssh_cidr_blocks" {
+  type        = list(string)
+  description = "CIDR blocks for SSH access to bastion host"
+  default     = ["0.0.0.0/0"]
+}
+
+variable "oap_instance_type" {
+  type        = string
+  description = "CPU, memory, storage and networking capacity for OAP 
instances"
+  default     = "c5.xlarge"
+}
+
+variable "ui_instance_type" {
   type        = string
-  description = "CPU, memory, storage and networking capacity for OAP and UI 
instances"
+  description = "CPU, memory, storage and networking capacity for UI instances"
   default     = "t2.medium"
 }
 
@@ -79,35 +117,10 @@ variable "extra_tags" {
   default     = {}
 }
 
-## VPC
-variable "cidr" {
-  type        = string
-  description = "CIDR for database tier"
-  default     = "11.0.0.0/16"
-}
-
-variable "private_subnets" {
-  type        = set(string)
-  description = "CIDR used for private subnets"
-  default     = ["11.0.1.0/24", "11.0.2.0/24", "11.0.3.0/24"]
-}
-
-variable "public_subnets" {
-  type        = set(string)
-  description = "CIDR used for public subnets"
-  default     = ["11.0.101.0/24", "11.0.102.0/24", "11.0.103.0/24"]
-}
-
-variable "database_subnets" {
-  type        = set(string)
-  description = "CIDR used for database subnets"
-  default     = ["11.0.104.0/24", "11.0.105.0/24", "11.0.106.0/24"]
-}
-
 ## Storage
 variable "storage" {
   type        = string
-  description = "Storage type for SkyWalking OAP, can be 'h2', or 
'rds-postgresql'"
+  description = "Storage type for SkyWalking OAP, can be `h2`, or 
`rds-postgresql`"
   default     = "rds-postgresql"
 
   validation {
@@ -116,39 +129,9 @@ variable "storage" {
   }
 }
 
-variable "db_name" {
-  type        = string
-  description = "Name of the database"
-  default     = "skywalking"
-}
-
-variable "db_username" {
-  type        = string
-  description = "Username for the database"
-  default     = "skywalking"
-}
-
-variable "db_password" {
-  type        = string
-  description = "Password for the database, if not set, a random password will 
be generated."
-  default     = null
-}
-
-variable "db_storage_size" {
-  type        = number
-  description = "Storage size for the database, in GB"
-  default     = 5
-}
-
-variable "db_max_storage_size" {
-  type        = number
-  description = "Maximum storage size for the database, in GB"
-  default     = 100
-}
-
-variable "db_instance_class" {
-  type        = string
-  description = "Instance class for the database"
-  default     = "db.t3.medium"
+variable "create_lb" {
+  type        = bool
+  description = "Create a load balancer for UI instances"
+  default     = true
 }
 
diff --git a/aws/rds-postgresql-main.tf b/aws/rds-postgresql-main.tf
index 58f7958..fd685c9 100644
--- a/aws/rds-postgresql-main.tf
+++ b/aws/rds-postgresql-main.tf
@@ -82,7 +82,7 @@ resource "aws_security_group" "allow_apps" {
     from_port       = 5432
     to_port         = 5432
     protocol        = "tcp"
-    security_groups = [aws_security_group.skywalking-oap.id]
+    security_groups = module.skywalking.oap_security_groups
   }
 
   egress {
diff --git a/aws/skywalking-main.tf b/aws/skywalking-main.tf
new file mode 100644
index 0000000..6ca40d1
--- /dev/null
+++ b/aws/skywalking-main.tf
@@ -0,0 +1,40 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+module "skywalking" {
+  source = "./modules/skywalking"
+
+  cluster_name = var.cluster_name
+  storage      = var.storage
+
+  oap_instance_count     = var.oap_instance_count
+  oap_instance_type      = var.oap_instance_type
+  oap_instance_subnet_id = element(module.vpc.private_subnets, 0)
+
+  ui_instance_count              = var.ui_instance_count
+  ui_instance_type               = var.ui_instance_type
+  ui_instance_subnet_id          = element(module.vpc.private_subnets, 0)
+  ui_instance_security_group_ids = var.create_lb ? 
aws_security_group.alb-skywalking-ui.*.id : []
+
+  bastion_enabled         = var.bastion_enabled
+  bastion_instance_type   = var.bastion_instance_type
+  bastion_ssh_cidr_blocks = var.bastion_ssh_cidr_blocks
+  public_key_path         = var.public_key_path
+
+  vpc_id                = module.vpc.vpc_id
+  vpc_bastion_subnet_id = element(module.vpc.public_subnets, 0)
+}
diff --git a/aws/skywalking-oap-output.tf b/aws/skywalking-oap-output.tf
deleted file mode 100644
index d785e1a..0000000
--- a/aws/skywalking-oap-output.tf
+++ /dev/null
@@ -1,22 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-output "skywalking_oap_ips" {
-  value       = ["${aws_instance.skywalking-oap.*.private_ip}"]
-  description = "The private IPs of the OAP instances"
-}
-
diff --git a/aws/bastion-output.tf b/aws/skywalking-outputs.tf
similarity index 65%
rename from aws/bastion-output.tf
rename to aws/skywalking-outputs.tf
index 03fc206..500eedc 100644
--- a/aws/bastion-output.tf
+++ b/aws/skywalking-outputs.tf
@@ -15,7 +15,22 @@
 # specific language governing permissions and limitations
 # under the License.
 
+output "oap_ips" {
+  value       = module.skywalking.oap_ips
+  description = "The private IPs of the OAP instances"
+}
+
+output "ui_ips" {
+  value       = module.skywalking.ui_ips
+  description = "The IPs of the SkyWalking UI instances"
+}
+
 output "bastion_ips" {
-  value       = aws_instance.bastion.*.public_ip
-  description = "The public IP that can be used to SSH into the bastion host."
+  value       = module.skywalking.bastion_ips
+  description = "The public IP that can be used to SSH into the bastion host"
+}
+
+output "ssh_user_key_file" {
+  value       = module.skywalking.ssh_user_key_file
+  description = "The SSH private key file to use to connect to the bastion 
host"
 }
diff --git a/aws/skywalking-ui-output.tf b/aws/skywalking-ui-output.tf
deleted file mode 100644
index 89abac4..0000000
--- a/aws/skywalking-ui-output.tf
+++ /dev/null
@@ -1,21 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-output "skywalking_ui_ips" {
-  value       = ["${aws_instance.skywalking-ui.*.private_ip}"]
-  description = "The IPs of the SkyWalking UI instances"
-}
diff --git a/aws/variables.tf b/aws/variables.tf
index dfdf1d6..03f73bd 100644
--- a/aws/variables.tf
+++ b/aws/variables.tf
@@ -61,9 +61,21 @@ variable "bastion_instance_type" {
   default     = "t2.micro"
 }
 
-variable "instance_type" {
+variable "bastion_ssh_cidr_blocks" {
+  type        = list(string)
+  description = "CIDR blocks for SSH access to bastion host"
+  default     = ["0.0.0.0/0"]
+}
+
+variable "oap_instance_type" {
+  type        = string
+  description = "CPU, memory, storage and networking capacity for OAP 
instances"
+  default     = "c5.xlarge"
+}
+
+variable "ui_instance_type" {
   type        = string
-  description = "CPU, memory, storage and networking capacity for OAP and UI 
instances"
+  description = "CPU, memory, storage and networking capacity for UI instances"
   default     = "t2.medium"
 }
 
@@ -152,3 +164,8 @@ variable "db_instance_class" {
   default     = "db.t3.medium"
 }
 
+variable "create_lb" {
+  type        = bool
+  description = "Create load balancer for SkyWalking UI"
+  default     = true
+}

Reply via email to