├── .gitignore ├── LICENSE ├── README.md ├── build-orm └── install.tf ├── compute.tf ├── data_sources.tf ├── image_subscription.tf ├── images └── create_orm_stack.png ├── locals.tf ├── network.tf ├── nsg.tf ├── oci_images.tf ├── outputs.tf ├── packer ├── README.md ├── cleanup.sh ├── env_vars.sh ├── images │ ├── cloudshell.png │ ├── comp_ocid.png │ └── public_network.png ├── installer.sh └── template.pkr.hcl ├── provider.tf.cli ├── schema.yaml ├── scripts └── example.sh ├── terraform.tfvars.template ├── variables.tf └── versions.tf /.gitignore: -------------------------------------------------------------------------------- 1 | # Local .terraform directories 2 | **/.terraform/* 3 | 4 | # .tfstate files 5 | *.tfstate 6 | *.tfstate.* 7 | *.zip* 8 | *.tfvars 9 | 10 | # Local .terraform lock files 11 | *.lock.* 12 | 13 | # modified env var example 14 | packer/env_vars.sh 15 | 16 | # General 17 | .DS_Store 18 | .AppleDouble 19 | .LSOverride 20 | 21 | # Icon must end with two \r 22 | Icon 23 | 24 | # Thumbnails 25 | ._* 26 | 27 | # Files that might appear in the root of a volume 28 | .DocumentRevisions-V100 29 | .fseventsd 30 | .Spotlight-V100 31 | .TemporaryItems 32 | .Trashes 33 | .VolumeIcon.icns 34 | .com.apple.timemachine.donotpresent 35 | 36 | # Directories potentially created on remote AFP share 37 | .AppleDB 38 | .AppleDesktop 39 | Network Trash Folder 40 | Temporary Items 41 | .apdisk 42 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2018-2025 Oracle and/or its affiliates. All rights reserved. 2 | 3 | The Universal Permissive License (UPL), Version 1.0 4 | 5 | Subject to the condition set forth below, permission is hereby granted to any person obtaining a copy of this 6 | software, associated documentation and/or data (collectively the "Software"), free of charge and under any and 7 | all copyright rights in the Software, and any and all patent rights owned or freely licensable by each licensor 8 | hereunder covering either (i) the unmodified Software as contributed to or provided by such licensor, or 9 | (ii) the Larger Works (as defined below), to deal in both 10 | 11 | (a) the Software, and 12 | (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if one is included with the Software 13 | (each a “Larger Work” to which the Software is contributed by such licensors), 14 | 15 | without restriction, including without limitation the rights to copy, create derivative works of, display, 16 | perform, and distribute the Software and make, use, sell, offer for sale, import, export, have made, and have 17 | sold the Software and the Larger Work(s), and to sublicense the foregoing rights on either these or other terms. 18 | 19 | This license is subject to the following condition: 20 | The above copyright notice and either this complete permission notice or at a minimum a reference to the UPL must 21 | be included in all copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO 24 | THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 26 | CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 27 | IN THE SOFTWARE. 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # oci-quickstart-template 2 | 3 | The [Oracle Cloud Infrastructure (OCI) Quick Start](https://github.com/oracle-quickstart?q=oci-quickstart) is a collection of examples that allow Oracle Cloud Infrastructure users to get a quick start deploying advanced infrastructure on OCI. 4 | 5 | The oci-quickstart-template repository contains the template that can be used for accelerating the construction of quickstarts that runs from local Terraform CLI, [OCI Resource Manager](https://docs.cloud.oracle.com/en-us/iaas/Content/ResourceManager/Concepts/resourcemanager.htm) and [OCI Cloud Shell](https://docs.cloud.oracle.com/en-us/iaas/Content/API/Concepts/cloudshellintro.htm). 6 | 7 | Simple is a sample quickstart terraform template that deploys a virtual machine on a Virtual Cloud Network. 8 | Simple can be customized to subscribe and launch Marketplace images, Platform images or Custom images. 9 | 10 | This repo is under active development. Building open source software is a community effort. We're excited to engage with the community building this. 11 | 12 | ## Resource Manager Deployment 13 | 14 | This Quick Start uses [OCI Resource Manager](https://docs.cloud.oracle.com/iaas/Content/ResourceManager/Concepts/resourcemanager.htm) to make deployment easy, sign up for an [OCI account](https://cloud.oracle.com/en_US/tryit) if you don't have one, and just click the button below: 15 | 16 | [![Deploy to Oracle Cloud](https://oci-resourcemanager-plugin.plugins.oci.oraclecloud.com/latest/deploy-to-oracle-cloud.svg)](https://cloud.oracle.com/resourcemanager/stacks/create?region=home&zipUrl=https://github.com/oracle-quickstart/oci-quickstart-template/archive/master.zip) 17 | 18 | After logging into the console you'll be taken through the same steps described 19 | in the [Deploy](#deploy) section below. 20 | 21 | 22 | Note, if you use this template to create another repo you'll need to change the link for the button to point at your repo. 23 | 24 | ## Local Development 25 | 26 | First off we'll need to do some pre deploy setup. That's all detailed [here](https://github.com/oracle/oci-quickstart-prerequisites). 27 | 28 | Note, the instructions below build a `.zip` file from you local copy for use in ORM. 29 | If you want to not use ORM and deploy with the terraform CLI you need to rename 30 | `provider.tf.cli -> provider.tf`. This is because authentication works slightly 31 | differently in ORM vs the CLI. This file is ignored by the build process below. 32 | 33 | Make sure you have terraform v0.14+ cli installed and accessible from your terminal. 34 | 35 | ### Build 36 | 37 | Simply `build` your package and follow the [Resource Manager instructions](https://docs.cloud.oracle.com/en-us/iaas/Content/ResourceManager/Tasks/managingstacksandjobs.htm#console) for how to create a stack. Prior to building the Stack, you may want to modify some parts of the deployment detailed below. 38 | 39 | In order to `build` the zip file with the latest changes you made to this code, you can simply go to [build-orm](./build-orm) folder and use terraform to generate a new zip file: 40 | 41 | At first time, you are required to initialize the terraform modules used by the template with `terraform init` command: 42 | 43 | ```bash 44 | $ terraform init 45 | 46 | Initializing the backend... 47 | 48 | Initializing provider plugins... 49 | - Finding latest version of hashicorp/archive... 50 | - Installing hashicorp/archive v2.1.0... 51 | - Installed hashicorp/archive v2.1.0 (signed by HashiCorp) 52 | 53 | Terraform has created a lock file .terraform.lock.hcl to record the provider 54 | selections it made above. Include this file in your version control repository 55 | so that Terraform can guarantee to make the same selections by default when 56 | you run "terraform init" in the future. 57 | 58 | Terraform has been successfully initialized! 59 | 60 | You may now begin working with Terraform. Try running "terraform plan" to see 61 | any changes that are required for your infrastructure. All Terraform commands 62 | should now work. 63 | 64 | If you ever set or change modules or backend configuration for Terraform, 65 | rerun this command to reinitialize your working directory. If you forget, other 66 | commands will detect it and remind you to do so if necessary. 67 | ``` 68 | 69 | Once terraform is initialized, just run `terraform apply` to generate ORM zip file. 70 | 71 | ```bash 72 | $ terraform apply 73 | 74 | data.archive_file.generate_zip: Refreshing state... 75 | 76 | Apply complete! Resources: 0 added, 0 changed, 0 destroyed. 77 | ``` 78 | 79 | This command will package the content of `simple` folder into a zip and will store it in the `build-orm\dist` folder. You can check the content of the file by running `unzip -l dist/orm.zip`: 80 | 81 | ```bash 82 | $ unzip -l dist/orm.zip 83 | Archive: dist/orm.zip 84 | Length Date Time Name 85 | --------- ---------- ----- ---- 86 | 1140 01-01-2049 00:00 compute.tf 87 | 680 01-01-2049 00:00 data_sources.tf 88 | 1632 01-01-2049 00:00 image_subscription.tf 89 | 1359 01-01-2049 00:00 locals.tf 90 | 13548 01-01-2049 00:00 schema.yaml 91 | 2001 01-01-2049 00:00 network.tf 92 | 2478 01-01-2049 00:00 nsg.tf 93 | 830 01-01-2049 00:00 oci_images.tf 94 | 1092 01-01-2049 00:00 outputs.tf 95 | 44 01-01-2049 00:00 scripts/example.sh 96 | 4848 01-01-2049 00:00 variables.tf 97 | 311 01-01-2049 00:00 versions.tf 98 | --------- ------- 99 | 29963 12 files 100 | ``` 101 | 102 | ### Deploy 103 | 104 | 1. [Login](https://console.us-ashburn-1.oraclecloud.com/resourcemanager/stacks/create) to Oracle Cloud Infrastructure to import the stack 105 | > `Home > Solutions & Platform > Resource Manager > Stacks > Create Stack` 106 | 107 | 2. Upload the `orm.zip` and provide a name and description for the stack 108 | ![Create Stack](./images/create_orm_stack.png) 109 | 110 | 3. Configure the Stack. The UI will present the variables to the user dynamically, based on their selections. These are the configuration options: 111 | 112 | > Compute Configuration 113 | 114 | | VARIABLE | DESCRIPTION | 115 | |----------------------------|-----------------------------------------------------------------------| 116 | |COMPUTE COMPARTMENT | Compartment for Compute resources, including Marketplace subscription | 117 | |INSTANCE NAME | Compute instance name| 118 | |DNS HOSTNAME LABEL | DNS Hostname| 119 | |COMPUTE SHAPE | Compatible Compute shape| 120 | |FLEX SHAPE OCPUS | Number of OCPUs, only available for VM.Standard.E3.Flex compute shape| 121 | |AVAILABILITY DOMAIN | Availability Domain| 122 | |PUBLIC SSH KEY STRING | RSA PUBLIC SSH key string used for sign in to the OS| 123 | 124 | > Virtual Cloud Network 125 | 126 | | VARIABLE | DESCRIPTION | 127 | |----------------------------|-----------------------------------------------------------------------| 128 | |NETWORK COMPARTMENT | Compartment for all Virtual Cloud Network resources| 129 | |NETWORK STRATEGY | `Create New VCN and Subnet`: Create new network resources during apply.
`Use Existing VCN and Subnet`: Let user select pre-existent network resources.| 130 | |CONFIGURATION STRATEGY | `Use Recommended Configuration`: Use default configuration defined by the Terraform template.
`Customize Network Configuration`: Allow user to customize network configuration such as name, dns label, cidr block for VCN and Subnet.| 131 | 132 | > Virtual Cloud Network - Customize Network Configuration 133 | 134 | | VARIABLE | DESCRIPTION | 135 | |----------------------------|-----------------------------------------------------------------------| 136 | |NAME | VCN Display Name| 137 | |DNS LABEL | VCN DNS LABEL| 138 | |CIDR BLOCK | The CIDR of the new Virtual Cloud Network (VCN). If you plan to peer this VCN with another VCN, the VCNs must not have overlapping CIDRs.| 139 | 140 | > Simple Subnet (visible only when `Customize Network Configuration` is selected) 141 | 142 | | VARIABLE | DESCRIPTION | 143 | |----------------------------|-----------------------------------------------------------------------| 144 | |SUBNET TYPE | `Public Subnet` or `Private Subnet`| 145 | |NAME | Subnet Display Name| 146 | |DNS LABEL | Subnet DNS LABEL| 147 | |CIDR BLOCK | The CIDR of the Subnet. Should not overlap with any other subnet CIDRs| 148 | |NETWORK SECURITY GROUP CONFIGURATION| `Use Recommended Configuration`: Use default configuration defined by the Terraform template.
`Customize Network Security Group`: Allow user to customize some basic network security group settings.| 149 | 150 | > Network Security Group (visible only when `Customize Network Security Group` is selected) 151 | 152 | | VARIABLE | DESCRIPTION | 153 | |----------------------------|-----------------------------------------------------------------------| 154 | |NAME | NSG Display Name| 155 | |ALLOWED INGRESS TRAFFIC (CIDR BLOCK)| WHITELISTED CIDR BLOCK for ingress traffic| 156 | |SSH PORT NUMBER | Default SSH PORT for ingress traffic| 157 | |HTTP PORT NUMBER | Default HTTP PORT for ingress traffic| 158 | |HTTPS PORT NUMBER | Default HTTPS PORT for ingress traffic| 159 | 160 | > Additional Configuration Options 161 | 162 | | VARIABLE | DESCRIPTION | 163 | |----------------------------|-----------------------------------------------------------------------| 164 | |TAG KEY NAME | Free-form tag key name| 165 | |TAG VALUE | Free-form tag value| 166 | 167 | 4. Click Next and Review the configuration. 168 | 5. Click Create button to confirm and create your ORM Stack. 169 | 6. On Stack Details page, you can now run `Terraform` commands to manage your infrastructure. You typically start with a plan then run apply to create and make changes to the infrastructure. More details below: 170 | 171 | | TERRAFORM ACTIONS | DESCRIPTION | 172 | |----------------------------|-----------------------------------------------------------------------| 173 | |Plan | `terraform plan` is used to create an execution plan. This command is a convenient way to check the execution plan prior to make any changes to the infrastructure resources.| 174 | |Apply | `terraform apply` is used to apply the changes required to reach the desired state of the configuration described by the template.| 175 | |Destroy | `terraform destroy` is used to destroy the Terraform-managed infrastructure.| 176 | 177 | ## Customize for Marketplace 178 | 179 | In case you wanted to make changes to this template to use a Marketplace image rather than a platform image or custom image, you need to make the following changes. 180 | 181 | 1. Configure Marketplace listing variables on [`variables.tf`](./variables.tf). 182 | 183 | | VARIABLES | DESCRIPTION | 184 | |----------------------------|-----------------------------------------------------------------------| 185 | |mp_subscription_enabled | Enable subscription to Marketplace.| 186 | |mp_listing_id | Marketplace App Catalog Listing OCID.| 187 | |mp_listing_resource_id | Marketplace Listing Image OCID.| 188 | |mp_listing_resource_version | Marketplace Listing Package/Resource Version (Reference value)| 189 | 190 | 2. Modify [`compute.tf`](./compute.tf) set `source_details` to refer to `local.compute_image_id` rather than `platform_image_id`. The `local.compute_image_id` holds the logic to either refer to the marketplace image or a custom image, based on the `mp_subscription_enabled` flag. 191 | 192 | ```hcl 193 | resource "oci_core_instance" "simple-vm" { 194 | availability_domain = local.availability_domain 195 | compartment_id = var.compute_compartment_ocid 196 | display_name = var.vm_display_name 197 | shape = var.vm_compute_shape 198 | 199 | dynamic "shape_config" { 200 | for_each = local.is_flex_shape 201 | content { 202 | ocpus = shape_config.value 203 | } 204 | } 205 | 206 | 207 | create_vnic_details { 208 | subnet_id = local.use_existing_network ? var.subnet_id : oci_core_subnet.simple_subnet[0].id 209 | display_name = var.subnet_display_name 210 | assign_public_ip = local.is_public_subnet 211 | hostname_label = var.hostname_label 212 | skip_source_dest_check = false 213 | nsg_ids = [oci_core_network_security_group.simple_nsg.id] 214 | } 215 | 216 | source_details { 217 | source_type = "image" 218 | #use a marketplace image or custom image: 219 | source_id = local.compute_image_id 220 | } 221 | 222 | ``` 223 | 2. Modify [`oci_images.tf`](./oci_images.tf) set `marketplace_source_images` map variable to refer to the marketplace images your Stack will launch. 224 | 225 | ```hcl 226 | 227 | variable "marketplace_source_images" { 228 | type = map(object({ 229 | ocid = string 230 | is_pricing_associated = bool 231 | compatible_shapes = list(string) 232 | })) 233 | default = { 234 | main_mktpl_image = { 235 | ocid = "ocid1.image.oc1.." 236 | is_pricing_associated = true 237 | compatible_shapes = [] 238 | } 239 | #Remove comment and add as many marketplace images that your stack references be replicated to other realms 240 | #supporting_image = { 241 | # ocid = "ocid1.image.oc1.." 242 | # is_pricing_associated = false 243 | # compatible_shapes = ["VM.Standard2.2", "VM.Standard.E2.1.Micro"] 244 | #} 245 | } 246 | } 247 | 248 | ``` 249 | 250 | 2. Run your tests using the Terraform CLI or build a new package and deploy on ORM. 251 | -------------------------------------------------------------------------------- /build-orm/install.tf: -------------------------------------------------------------------------------- 1 | variable "save_to" { 2 | default = "" 3 | } 4 | 5 | data "archive_file" "generate_zip" { 6 | type = "zip" 7 | output_path = (var.save_to != "" ? "${var.save_to}/orm.zip" : "${path.module}/dist/orm.zip") 8 | source_dir = "../" 9 | excludes = ["packer",".terraform.lock.hcl","terraform.tfstate", "terraform.tfvars.template", "terraform.tfvars", "provider.tf", ".terraform", "build-orm", "images", "README.md", "terraform.", "terraform.tfstate.backup", "test", "simple", ".git", "README", ".github", ".gitignore", ".DS_Store", "LICENSE","diagram",] 10 | } 11 | -------------------------------------------------------------------------------- /compute.tf: -------------------------------------------------------------------------------- 1 | resource "oci_core_instance" "simple-vm" { 2 | availability_domain = local.availability_domain 3 | compartment_id = var.compartment_ocid 4 | display_name = var.vm_display_name 5 | shape = var.vm_compute_shape 6 | 7 | dynamic "shape_config" { 8 | for_each = local.is_flex_shape 9 | content { 10 | ocpus = shape_config.value 11 | } 12 | } 13 | 14 | 15 | create_vnic_details { 16 | subnet_id = local.use_existing_network ? var.subnet_id : oci_core_subnet.simple_subnet[0].id 17 | display_name = var.subnet_display_name 18 | assign_public_ip = local.is_public_subnet 19 | hostname_label = var.hostname_label 20 | skip_source_dest_check = false 21 | nsg_ids = [oci_core_network_security_group.simple_nsg.id] 22 | } 23 | 24 | source_details { 25 | source_type = "image" 26 | source_id = local.platform_image_id 27 | #use a marketplace image or custom image: 28 | #source_id = local.compute_image_id 29 | } 30 | 31 | lifecycle { 32 | ignore_changes = [ 33 | source_details[0].source_id 34 | ] 35 | } 36 | 37 | metadata = { 38 | ssh_authorized_keys = var.ssh_public_key 39 | user_data = base64encode(file("./scripts/example.sh")) 40 | } 41 | 42 | freeform_tags = {(var.tag_key_name) = (var.tag_value)} 43 | } 44 | -------------------------------------------------------------------------------- /data_sources.tf: -------------------------------------------------------------------------------- 1 | data "oci_identity_availability_domain" "ad" { 2 | compartment_id = var.tenancy_ocid 3 | ad_number = var.availability_domain_number 4 | } 5 | 6 | data "oci_core_images" "autonomous_ol7" { 7 | compartment_id = var.compartment_ocid 8 | operating_system = "Oracle Autonomous Linux" 9 | sort_by = "TIMECREATED" 10 | sort_order = "DESC" 11 | state = "AVAILABLE" 12 | 13 | # filter restricts to OL 7 14 | filter { 15 | name = "operating_system_version" 16 | values = ["7\\.[0-9]"] 17 | regex = true 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /image_subscription.tf: -------------------------------------------------------------------------------- 1 | #Get Image Agreement 2 | resource "oci_core_app_catalog_listing_resource_version_agreement" "mp_image_agreement" { 3 | count = local.mp_subscription_enabled 4 | 5 | listing_id = local.listing_id 6 | listing_resource_version = local.listing_resource_version 7 | } 8 | 9 | #Accept Terms and Subscribe to the image, placing the image in a particular compartment 10 | resource "oci_core_app_catalog_subscription" "mp_image_subscription" { 11 | count = local.mp_subscription_enabled 12 | 13 | compartment_id = var.compartment_ocid 14 | eula_link = oci_core_app_catalog_listing_resource_version_agreement.mp_image_agreement[0].eula_link 15 | listing_id = oci_core_app_catalog_listing_resource_version_agreement.mp_image_agreement[0].listing_id 16 | listing_resource_version = oci_core_app_catalog_listing_resource_version_agreement.mp_image_agreement[0].listing_resource_version 17 | oracle_terms_of_use_link = oci_core_app_catalog_listing_resource_version_agreement.mp_image_agreement[0].oracle_terms_of_use_link 18 | signature = oci_core_app_catalog_listing_resource_version_agreement.mp_image_agreement[0].signature 19 | time_retrieved = oci_core_app_catalog_listing_resource_version_agreement.mp_image_agreement[0].time_retrieved 20 | 21 | timeouts { 22 | create = "20m" 23 | } 24 | } 25 | 26 | # Gets the partner image subscription 27 | data "oci_core_app_catalog_subscriptions" "mp_image_subscription" { 28 | count = local.mp_subscription_enabled 29 | 30 | compartment_id = var.compartment_ocid 31 | listing_id = local.listing_id 32 | 33 | filter { 34 | name = "listing_resource_version" 35 | values = [local.listing_resource_version] 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /images/create_orm_stack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-quickstart/oci-quickstart-template/f14cb63748cbdafb80cf301cfc26769c8560ebf6/images/create_orm_stack.png -------------------------------------------------------------------------------- /locals.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | 3 | # Logic to use AD name provided by user input on ORM or to lookup for the AD name when running from CLI 4 | availability_domain = (var.availability_domain_name != "" ? var.availability_domain_name : data.oci_identity_availability_domain.ad.name) 5 | 6 | # local.use_existing_network referenced in network.tf 7 | use_existing_network = var.network_strategy == var.network_strategy_enum["USE_EXISTING_VCN_SUBNET"] ? true : false 8 | 9 | # local.is_public_subnet referenced in compute.tf 10 | is_public_subnet = var.subnet_type == var.subnet_type_enum["PUBLIC_SUBNET"] ? true : false 11 | 12 | # Logic to select Oracle Autonomous Linux 7 platform image (version pegged in data source filter) 13 | platform_image_id = data.oci_core_images.autonomous_ol7.images[0].id 14 | 15 | # Logic to choose a custom image or a marketplace image. 16 | compute_image_id = var.mp_subscription_enabled ? var.mp_listing_resource_id : var.custom_image_id 17 | 18 | # Local to control subscription to Marketplace image. 19 | mp_subscription_enabled = var.mp_subscription_enabled ? 1 : 0 20 | 21 | # Marketplace Image listing variables - required for subscription only 22 | listing_id = var.mp_listing_id 23 | listing_resource_id = var.mp_listing_resource_id 24 | listing_resource_version = var.mp_listing_resource_version 25 | 26 | 27 | is_flex_shape = var.vm_compute_shape == "VM.Standard.E3.Flex" ? [var.vm_flex_shape_ocpus]:[] 28 | 29 | } 30 | -------------------------------------------------------------------------------- /network.tf: -------------------------------------------------------------------------------- 1 | resource "oci_core_vcn" "simple" { 2 | count = local.use_existing_network ? 0 : 1 3 | cidr_block = var.vcn_cidr_block 4 | dns_label = substr(var.vcn_dns_label, 0, 15) 5 | compartment_id = var.compartment_ocid 6 | display_name = var.vcn_display_name 7 | 8 | freeform_tags = {(var.tag_key_name) = (var.tag_value)} 9 | } 10 | 11 | #IGW 12 | resource "oci_core_internet_gateway" "simple_internet_gateway" { 13 | count = local.use_existing_network ? 0 : 1 14 | compartment_id = var.compartment_ocid 15 | vcn_id = oci_core_vcn.simple[count.index].id 16 | enabled = "true" 17 | display_name = "${var.vcn_display_name}-igw" 18 | 19 | freeform_tags = {(var.tag_key_name) = (var.tag_value)} 20 | } 21 | 22 | #simple subnet 23 | resource "oci_core_subnet" "simple_subnet" { 24 | count = local.use_existing_network ? 0 : 1 25 | cidr_block = var.subnet_cidr_block 26 | compartment_id = var.compartment_ocid 27 | vcn_id = oci_core_vcn.simple[count.index].id 28 | display_name = var.subnet_display_name 29 | dns_label = substr(var.subnet_dns_label, 0, 15) 30 | prohibit_public_ip_on_vnic = ! local.is_public_subnet 31 | 32 | freeform_tags = {(var.tag_key_name) = (var.tag_value)} 33 | } 34 | 35 | resource "oci_core_route_table" "simple_route_table" { 36 | count = local.use_existing_network ? 0 : 1 37 | compartment_id = var.compartment_ocid 38 | vcn_id = oci_core_vcn.simple[count.index].id 39 | display_name = "${var.subnet_display_name}-rt" 40 | 41 | route_rules { 42 | network_entity_id = oci_core_internet_gateway.simple_internet_gateway[count.index].id 43 | destination = "0.0.0.0/0" 44 | destination_type = "CIDR_BLOCK" 45 | } 46 | 47 | freeform_tags = {(var.tag_key_name) = (var.tag_value)} 48 | } 49 | 50 | resource "oci_core_route_table_attachment" "route_table_attachment" { 51 | count = local.use_existing_network ? 0 : 1 52 | subnet_id = oci_core_subnet.simple_subnet[count.index].id 53 | route_table_id = oci_core_route_table.simple_route_table[count.index].id 54 | } 55 | -------------------------------------------------------------------------------- /nsg.tf: -------------------------------------------------------------------------------- 1 | resource "oci_core_network_security_group" "simple_nsg" { 2 | #Required 3 | compartment_id = var.compartment_ocid 4 | vcn_id = local.use_existing_network ? var.vcn_id : oci_core_vcn.simple.0.id 5 | 6 | #Optional 7 | display_name = var.nsg_display_name 8 | 9 | freeform_tags = {(var.tag_key_name) = (var.tag_value)} 10 | } 11 | 12 | # Allow Egress traffic to all networks 13 | resource "oci_core_network_security_group_security_rule" "simple_rule_egress" { 14 | network_security_group_id = oci_core_network_security_group.simple_nsg.id 15 | 16 | direction = "EGRESS" 17 | protocol = "all" 18 | destination = "0.0.0.0/0" 19 | 20 | } 21 | 22 | # Allow SSH (TCP port 22) Ingress traffic from any network 23 | resource "oci_core_network_security_group_security_rule" "simple_rule_ssh_ingress" { 24 | network_security_group_id = oci_core_network_security_group.simple_nsg.id 25 | protocol = "6" 26 | direction = "INGRESS" 27 | source = var.nsg_source_cidr 28 | stateless = false 29 | 30 | tcp_options { 31 | destination_port_range { 32 | min = var.nsg_ssh_port 33 | max = var.nsg_ssh_port 34 | } 35 | } 36 | } 37 | 38 | # Allow HTTPS (TCP port 443) Ingress traffic from any network 39 | resource "oci_core_network_security_group_security_rule" "simple_rule_https_ingress" { 40 | network_security_group_id = oci_core_network_security_group.simple_nsg.id 41 | protocol = "6" 42 | direction = "INGRESS" 43 | source = var.nsg_source_cidr 44 | stateless = false 45 | 46 | tcp_options { 47 | destination_port_range { 48 | min = var.nsg_https_port 49 | max = var.nsg_https_port 50 | } 51 | } 52 | } 53 | 54 | # Allow HTTP (TCP port 80) Ingress traffic from any network 55 | resource "oci_core_network_security_group_security_rule" "simple_rule_http_ingress" { 56 | network_security_group_id = oci_core_network_security_group.simple_nsg.id 57 | protocol = "6" 58 | direction = "INGRESS" 59 | source = var.nsg_source_cidr 60 | stateless = false 61 | 62 | tcp_options { 63 | destination_port_range { 64 | min = var.nsg_http_port 65 | max = var.nsg_http_port 66 | } 67 | } 68 | } 69 | 70 | # Allow ANY Ingress traffic from within simple vcn 71 | resource "oci_core_network_security_group_security_rule" "simple_rule_all_simple_vcn_ingress" { 72 | network_security_group_id = oci_core_network_security_group.simple_nsg.id 73 | protocol = "all" 74 | direction = "INGRESS" 75 | source = var.vcn_cidr_block 76 | stateless = false 77 | } 78 | -------------------------------------------------------------------------------- /oci_images.tf: -------------------------------------------------------------------------------- 1 | #File used only if Stack is a Marketplace Stack 2 | #Update based on Marketplace Listing - App Install Package - Image Oracle Cloud Identifier 3 | #Each element is a single image from Marketpalce Catalog. Elements' name in map is arbitrary 4 | 5 | 6 | variable "marketplace_source_images" { 7 | type = map(object({ 8 | ocid = string 9 | is_pricing_associated = bool 10 | compatible_shapes = list(string) 11 | })) 12 | default = { 13 | main_mktpl_image = { 14 | ocid = "ocid1.image.oc1.." 15 | is_pricing_associated = true 16 | compatible_shapes = [] 17 | } 18 | #Remove comment and add as many marketplace images that your stack references be replicated to other realms 19 | #supporting_image = { 20 | # ocid = "ocid1.image.oc1.." 21 | # is_pricing_associated = false 22 | # compatible_shapes = ["VM.Standard2.2", "VM.Standard.E2.1.Micro"] 23 | #} 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /outputs.tf: -------------------------------------------------------------------------------- 1 | ### 2 | # compute.tf outputs 3 | ### 4 | 5 | output "instance_id" { 6 | value = oci_core_instance.simple-vm.id 7 | } 8 | 9 | output "instance_public_ip" { 10 | value = oci_core_instance.simple-vm.public_ip 11 | } 12 | 13 | output "instance_private_ip" { 14 | value = oci_core_instance.simple-vm.private_ip 15 | } 16 | 17 | output "instance_https_url" { 18 | value = (local.is_public_subnet ? "https://${oci_core_instance.simple-vm.public_ip}" : "https://${oci_core_instance.simple-vm.private_ip}") 19 | } 20 | 21 | ### 22 | # network.tf outputs 23 | ### 24 | 25 | output "vcn_id" { 26 | value = ! local.use_existing_network ? join("", oci_core_vcn.simple.*.id) : var.vcn_id 27 | } 28 | 29 | output "subnet_id" { 30 | value = ! local.use_existing_network ? join("", oci_core_subnet.simple_subnet.*.id) : var.subnet_id 31 | } 32 | 33 | output "vcn_cidr_block" { 34 | value = ! local.use_existing_network ? join("", oci_core_vcn.simple.*.cidr_block) : var.vcn_cidr_block 35 | } 36 | 37 | output "nsg_id" { 38 | value = join("", oci_core_network_security_group.simple_nsg.*.id) 39 | } 40 | 41 | ### 42 | # image_subscription.tf outputs 43 | ### 44 | 45 | output "subscription" { 46 | value = data.oci_core_app_catalog_subscriptions.mp_image_subscription.*.app_catalog_subscriptions 47 | } 48 | -------------------------------------------------------------------------------- /packer/README.md: -------------------------------------------------------------------------------- 1 | # oci-quickstart-template 2 | Packer is a tool provided by Hashicorp that allows you to automate creation of your machine images. 3 | 4 | ## Setup 5 | 6 | The `packer` binary can be installed from [here](https://developer.hashicorp.com/packer/tutorials/docker-get-started/get-started-install-cli). While it is not strictly required, the [OCI builder](https://developer.hashicorp.com/packer/plugins/builders/oracle/oci) for `packer` looks at the [config file](https://docs.oracle.com/en-us/iaas/Content/API/Concepts/sdkconfig.htm#SDK_and_CLI_Configuration_File) for the OCI SDK/CLI by default. 7 | These instructions assume you have the CLI installed. The OCI CLI can be installed from [here](https://docs.oracle.com/en-us/iaas/Content/API/SDKDocs/cliinstall.htm) 8 | and set up by following these [instructions](https://docs.oracle.com/en-us/iaas/Content/API/SDKDocs/cliinstall.htm#configfile). 9 | If it is not installed you will see errors for undefined variables in later steps. 10 | 11 | 12 | ## Instructions 13 | 1. Clone the oci-quickstart-template repository: 14 | ``` 15 | git clone https://github.com/oracle-quickstart/oci-quickstart-template.git 16 | cd oci-quickstart-template/packer 17 | ``` 18 | 2. Before we can build the image, we must create network components in our tenancy 19 | for an instance (or VM) to exist in. If you don't already have a VCN, log in to your tenancy and go to *Menu -> Networking -> Virtual Cloud Network -> Start VCN Wizard*. Default values should be fine. 20 | [Follow the Networking Quickstart to create a network](https://docs.cloud.oracle.com/en-us/iaas/Content/Network/Tasks/quickstartnetworking.htm) 21 | 22 | 3. Modify `env_vars.sh` and fill it with appropriate values from your tenancy. [See below](#how-to-determine-variables) for instructions on ways to obtain these values. Note, these 23 | values are the ones that are specific to your tenancy. 24 | ``` 25 | export PACKER_availibilty_domain="" 26 | export PACKER_compartment_ocid="" 27 | export PACKER_subnet_ocid="" 28 | export PACKER_my_secret="" 29 | ``` 30 | 4. Source the ```env_vars.sh``` file modified above: 31 | ``` 32 | source env_vars.sh 33 | ``` 34 | 35 | 5. Validate the packer file: 36 | ``` 37 | packer validate template.pkr.hcl 38 | The configuration is valid. 39 | ``` 40 | 41 | 6. Create the image: 42 | ``` 43 | packer build template.pkr.hcl 44 | 45 | oracle-oci.builder_vm: output will be in this color. 46 | 47 | ==> oracle-oci.builder_vm: Creating temporary ssh key for instance... 48 | ==> oracle-oci.builder_vm: Creating instance... 49 | ==> oracle-oci.builder_vm: Created instance (ocid1.instance.oc1.iad.anuwcljsugt6wmqca77wn3bb77nefpsgpuqnjsk4hglf2r563ymxeg4hfdbq). 50 | ==> oracle-oci.builder_vm: Waiting for instance to enter 'RUNNING' state... 51 | ==> oracle-oci.builder_vm: Instance 'RUNNING'. 52 | [...] 53 | ==> oracle-oci.builder_vm: Created image (ocid1.image.oc1.iad.aaaaaaaagwmrt5k7rdg4od4kp3n3lbowphexjrvhlysczlk2bqzjcrtmaidq). 54 | ==> oracle-oci.builder_vm: Terminating instance (ocid1.instance.oc1.iad.anuwcljsugt6wmqca77wn3bb77nefpsgpuqnjsk4hglf2r563ymxeg4hfdbq)... 55 | ==> oracle-oci.builder_vm: Terminated instance. 56 | Build 'oracle-oci.builder_vm' finished after 4 minutes 43 seconds. 57 | 58 | ==> Wait completed after 4 minutes 43 seconds 59 | 60 | ==> Builds finished. The artifacts of successful builds are: 61 | --> oracle-oci.builder_vm: An image was created: 'mybuild-VM.Standard.E4.Flex-20230525181128' (OCID: ocid1.image.oc1.iad.aaaaaaaagwmrt5k7rdg4od4kp3n3lbowphexjrvhlysczlk2bqzjcrtmaidq) in region 'us-ashburn-1' 62 | ``` 63 | 64 | 7. Done! Check you tenancy for the resulting image under *Menu -> Compute -> Custom Images*. 65 | You now have a custom image based on OL 8 built from `template.pkr.hcl` with the 66 | name `${var.imgprefix}-${var.shape}-${local.timestamp}` 67 | 68 | 69 | ## Variables, Provisioners, and Changing the Build 70 | 71 | ### Variables 72 | This repo and example template have variables defined in 3 places: 73 | - The default CLI config implicitly. 74 | - Tenancy specific variables in `env_vars.sh` 75 | - Non-tenancy specific variables in `template.pkr.hcl` 76 | 77 | Note, the variable `my_secret` is not required but is just an example of passing 78 | a secret to the provisioners in the template. It and references to it can be removed. It was defined as an env var to discourage committing it's value. 79 | 80 | The variables in the template can be changed there or overridden. For example when 81 | testing your build you may want to skip the actual image creation, just run: 82 | `packer build --var skip_image=true template.pkr.hcl` 83 | 84 | ### Provisioners 85 | The file `template.pkr.hcl` contains 4 example provisioners: 86 | - An inline shell example that echo's some strings and touches a file. 87 | - A shell example that copies `installer.sh` to the instance and runs it. 88 | - A file provisioner example that copies this readme to the instance and names it `test_file`. 89 | - A shell provisioner that runs the `oci-image-cleanup` command. 90 | 91 | The `oci-image-cleanup` is part of the [oci-utils](https://github.com/oracle/oci-utils) 92 | package. It clears ssh keys, logs, etc. 93 | 94 | ### Changing the Build 95 | 96 | All the 4 provisioners are just examples. You can edit them to install whatever applications are required or remove them. However, running the cleanup script is a best practice as it removes existing ssh keys and resets cloud-init so that instances booted from your custom image behave as if this is their first boot. 97 | 98 | _**However, you must run the cleanup script**_ if using this template to build an image for [OCI Marketplace](https://docs.oracle.com/en-us/iaas/Content/partner-portal/partner-portal_gs-what_s_oracle_cloud_marketplace_partner_portal.htm), if you do not the image will not pass validation. 99 | 100 | Other provisioners, like a [local shell](https://developer.hashicorp.com/packer/docs/provisioners/shell-local) provisioner or an [ansible](https://developer.hashicorp.com/packer/plugins/provisioners/ansible/ansible) provisioner can be added. 101 | 102 | --- 103 | 104 | ## How to Determine Variables 105 | 106 | ![Cloud Shell](images/cloudshell.png) 107 | 108 | Users will need to log into their tenancy to find the required information for setting the environment variables. One helpful tool is the Cloud Shell feature that can be accessed from the users tenancy homepage. By typing the commands below into the cloudshell terminal, users can get the required key/value pairs. The following direct link will open will the users tenancy and open a Cloud Shell embedded terminal: 109 | 110 | https://cloud.oracle.com/?cloudshell=true 111 | 112 |
PACKER_availibilty_domain

113 | 114 | The list of Availibility Domains available to a tenancy can be obtained using the following command: 115 | ``` 116 | $> oci iam availability-domain list | jq -r '.data[].name' 117 | IYfK:US-ASHBURN-AD-1 118 | IYfK:US-ASHBURN-AD-2 119 | IYfK:US-ASHBURN-AD-3 120 | ``` 121 |

122 | 123 | 124 |
PACKER_compartment_ocid

125 | 126 | The list of Compartment names and corresponding ocids available to a tenancy can be listed using the following command: 127 | ``` 128 | $> oci iam compartment list | jq -r '.data[] | .name + " = " + .id' 129 | TestCompartment = ocid1.compartment.oc1..aaaaaaaay6xopmxqb6oz52m3hdcinhknyagicj6764xx2cotffzpvolhwcsq 130 | ``` 131 | See the [Compartments](https://cloud.oracle.com/identity/compartments) page for a list of compartments in this tenancy. Click "Create Compartment" or click an existing Compartment to get the ocid. 132 | 133 | ![ScreenShot](images/comp_ocid.png) 134 | 135 |

136 | 137 |
PACKER_subnet_ocid

138 | 139 | See the Virtual Cloud Networks page for a list of networks in this tenancy. Click "Networking Quickstart" or click an existing network to get the ocid. 140 | 141 | *IMPORTANT: The ocid MUST be for the Public Subnet* 142 | 143 | ![ScreenShot](images/public_network.png) 144 | 145 |

146 | 147 | 148 |
base_image_ocid 149 |

150 | 151 | The list of platform image names and corresponding ocids available to a tenancy can be listed using the following command: 152 | ``` 153 | $> oci compute image list -c | jq -r '.data[] | ."display-name" + " = " + ."id"' 154 | Windows-Server-2016-Standard-Edition-VM-Gen2-2020.03.16-0 = ocid1.image.oc1.iad.aaaaaaaaafrffa5esbcbcmkqappz37wjkrwh4uzpcmuixx4bcnyi4ljqmeya 155 | Oracle-Linux-7.7-2020.03.23-0 = ocid1.image.oc1.iad.aaaaaaaa6tp7lhyrcokdtf7vrbmxyp2pctgg4uxvt4jz4vc47qoc2ec4anha 156 | Canonical-Ubuntu-18.04-2020.03.17-0 = ocid1.image.oc1.iad.aaaaaaaa7bcrfylytqnbsqcd6jwhp2o4m6wj4lxufo3bmijnkdbfr37wu6oa 157 | [...] 158 | ``` 159 | A complete list of Base Images available within OCI can be seen on the [OCI All Image Families](https://docs.cloud.oracle.com/en-us/iaas/images/) page. (Click under "Read More" to get the Image ocid for a particular Image and Region.) 160 |

161 |
162 | 163 | 164 |
shape

165 | 166 | The list of Compute Shapes available to a tenancy can be listed using the following command: 167 | ``` 168 | $> oci compute shape list -c | jq -r '.data[].shape' 169 | VM.Standard2.1 170 | VM.Standard2.2 171 | [...] 172 | ``` 173 | The list of available Compute Shapes is determined by the Service Limits of the tenancy. See the Tenancy Details page under *Service Limits -> + Compute* for the list of Compute Shapes available to your tenancy. Additional Compute Shapes can be requested by clicking the "Request a service limit increase" link on the *Tenanacy Details* page. 174 | 175 | The complete list of Compute Shapes available within OCI can also be seen on the [OCI Compute Shapes](https://docs.cloud.oracle.com/en-us/iaas/Content/Compute/References/computeshapes.htm) listings page. 176 |

177 | 178 | 179 | 180 | 181 |
ssh_username

182 | 183 | Oracle Linux ssh user is ```opc``` 184 | 185 | CentOS ssh user is ```opc``` 186 | 187 | Ubuntu ssh user is ```ubuntu``` 188 |

189 | -------------------------------------------------------------------------------- /packer/cleanup.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | BASE_IMAGE="" 4 | ORACLE_LINUX="ORACLE_LINUX" 5 | CENTOS="CENTOS" 6 | UBUNTU="UBUNTU" 7 | 8 | ################################################# 9 | ## Determine the base image (platform) we are on. 10 | ## 11 | ## 1) Oracle Linux will have the oci-image-cleanup 12 | ## script installed by default on the image. 13 | ## 14 | ## 2) CentOS will have a /etc/redhat-release file. 15 | ## 16 | ## 3) Ubuntu distro will have the "Ubuntu" string 17 | ## output a part of the `uname -a` command. 18 | ################################################## 19 | 20 | if [ -f /usr/libexec/oci-image-cleanup ]; then 21 | BASE_IMAGE=$ORACLE_LINUX 22 | elif [ -f /etc/redhat-release ]; then 23 | BASE_IMAGE=$CENTOS 24 | elif uname -a | grep -i "Ubuntu" > /dev/null 2>&1 ; then 25 | BASE_IMAGE=$UBUNTU 26 | fi 27 | #echo Base Image = \"$BASE_IMAGE\" 28 | 29 | 30 | ################################################# 31 | ## Run the oci-image-cleanup script. This scrip 32 | ## comes by default on Oracle Linux. On CentOS 33 | ## platform we need to download it. 34 | ################################################## 35 | 36 | if [ "$BASE_IMAGE" == "$ORACLE_LINUX" ]; then 37 | sudo /usr/libexec/oci-image-cleanup -f 38 | elif [[ "$BASE_IMAGE" == "$CENTOS" || "$BASE_IMAGE" == "$UBUNTU" ]]; then 39 | wget -P /tmp https://raw.githubusercontent.com/oracle/oci-utils/master/libexec/oci-image-cleanup 40 | chmod 700 /tmp/oci-image-cleanup 41 | sudo /tmp/oci-image-cleanup -f 42 | fi 43 | -------------------------------------------------------------------------------- /packer/env_vars.sh: -------------------------------------------------------------------------------- 1 | export PACKER_availibilty_domain="" 2 | export PACKER_compartment_ocid="" 3 | export PACKER_subnet_ocid="" 4 | export PACKER_my_secret="" 5 | -------------------------------------------------------------------------------- /packer/images/cloudshell.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-quickstart/oci-quickstart-template/f14cb63748cbdafb80cf301cfc26769c8560ebf6/packer/images/cloudshell.png -------------------------------------------------------------------------------- /packer/images/comp_ocid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-quickstart/oci-quickstart-template/f14cb63748cbdafb80cf301cfc26769c8560ebf6/packer/images/comp_ocid.png -------------------------------------------------------------------------------- /packer/images/public_network.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-quickstart/oci-quickstart-template/f14cb63748cbdafb80cf301cfc26769c8560ebf6/packer/images/public_network.png -------------------------------------------------------------------------------- /packer/installer.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "Hello World!" > HelloWorld.txt 4 | -------------------------------------------------------------------------------- /packer/template.pkr.hcl: -------------------------------------------------------------------------------- 1 | 2 | variable "availibilty_domain" { 3 | type = string 4 | default = env("PACKER_availibilty_domain") 5 | } 6 | 7 | variable "base_image_ocid" { 8 | type = string 9 | default = "ocid1.image.oc1.iad.aaaaaaaazavxtitjiojkyivwwb72pn2vcvnoxirpgkhf26i2ku4egieknkxq" 10 | # Oracle-Linux-8.7-2023.04.25-0 11 | # ocid1.image.oc1.iad.aaaaaaaazavxtitjiojkyivwwb72pn2vcvnoxirpgkhf26i2ku4egieknkxq 12 | } 13 | 14 | variable "compartment_ocid" { 15 | type = string 16 | default = env("PACKER_compartment_ocid") 17 | } 18 | 19 | variable "my_secret" { 20 | type = string 21 | default = env("PACKER_my_secret") 22 | } 23 | 24 | variable "shape" { 25 | type = string 26 | default = "VM.Standard.E4.Flex" 27 | } 28 | 29 | variable "ocpus" { 30 | type = number 31 | default = 2 32 | } 33 | 34 | variable "ssh_username" { 35 | type = string 36 | default = "opc" 37 | } 38 | 39 | variable "subnet_ocid" { 40 | type = string 41 | default = env("PACKER_subnet_ocid") 42 | } 43 | 44 | variable "type" { 45 | type = string 46 | default = "oracle-oci" 47 | } 48 | 49 | variable "skip_image" { 50 | type = bool 51 | default = false 52 | } 53 | 54 | variable "imgprefix" { 55 | type = string 56 | default = "mybuild" 57 | } 58 | 59 | locals { 60 | timestamp = regex_replace(timestamp(), "[- TZ:]", "") 61 | is_flex_shape = substr(var.shape, -5, -1) == ".Flex" ? [1] : [] 62 | } 63 | 64 | packer { 65 | required_plugins { 66 | oracle = { 67 | version = ">= 1.0.4" 68 | source = "github.com/hashicorp/oracle" 69 | } 70 | } 71 | } 72 | 73 | source "oracle-oci" "builder_vm" { 74 | image_name = "${var.imgprefix}-${var.shape}-${local.timestamp}" 75 | availability_domain = var.availibilty_domain 76 | base_image_ocid = var.base_image_ocid 77 | compartment_ocid = var.compartment_ocid 78 | shape = var.shape 79 | ssh_username = var.ssh_username 80 | subnet_ocid = var.subnet_ocid 81 | 82 | dynamic "shape_config" { 83 | for_each = local.is_flex_shape 84 | content { 85 | ocpus = var.ocpus 86 | } 87 | } 88 | 89 | skip_create_image = var.skip_image 90 | } 91 | 92 | build { 93 | sources = ["source.oracle-oci.builder_vm"] 94 | 95 | provisioner "shell" { 96 | expect_disconnect = "true" 97 | inline = ["cd ~", "echo Hello World!", "echo ${var.my_secret} > /dev/null", "touch foobar.txt"] 98 | } 99 | 100 | provisioner "shell" { 101 | script = "installer.sh" 102 | } 103 | 104 | provisioner "file" { 105 | source = "README.md" 106 | destination = "~/test_file" 107 | } 108 | 109 | provisioner "shell" { 110 | script = "cleanup.sh" 111 | } 112 | 113 | } 114 | -------------------------------------------------------------------------------- /provider.tf.cli: -------------------------------------------------------------------------------- 1 | provider "oci" { 2 | tenancy_ocid = var.tenancy_ocid 3 | user_ocid = var.user_ocid 4 | fingerprint = var.fingerprint 5 | private_key_path = var.private_key_path 6 | region = var.region 7 | } 8 | 9 | # Variables required by the OCI Provider only when running Terraform CLI with standard user based Authentication 10 | variable "user_ocid" { 11 | } 12 | 13 | variable "fingerprint" { 14 | } 15 | 16 | variable "private_key_path" { 17 | } 18 | -------------------------------------------------------------------------------- /schema.yaml: -------------------------------------------------------------------------------- 1 | # Title shown in Application Information tab. 2 | title: Sample Marketplace Stack / ORM Application - BYOL 3 | # Sub Title shown in Application Information tab. 4 | description: This is a Sample Marketplace Stack / ORM Application - BYOL 5 | schemaVersion: 1.1.0 6 | version: "20190304" 7 | 8 | # URL of Logo Icon used on Application Information tab. You can copy the contentId from the Marketplace listing logo URL in the Marketplace Partner portal. 9 | # (Optional) 10 | logoUrl: https://cloudmarketplace.oracle.com/marketplace/content?contentId=71617800 11 | 12 | # Used in Application Information tab to Hyperlink Title and Logo to the Marketplace 13 | # Listing. 14 | # Also used to link to Listing Usage section for "View Instructions". 15 | # (Optional) If it is missing, Application Information uses the 16 | # "marketplace-listing-id" tag for the same purpose. 17 | source: 18 | type: marketplace 19 | reference: 12345 20 | 21 | locale: "en" 22 | variableGroups: 23 | - title: "Hidden Variable Group" 24 | visible: false 25 | variables: 26 | #"variables used internally - not exposed to end user" 27 | - tenancy_ocid 28 | - region 29 | - mp_listing_id 30 | - mp_listing_resource_id 31 | - mp_listing_resource_version 32 | - availability_domain_number 33 | - mp_subscription_enabled 34 | - network_strategy_enum 35 | - subnet_type_enum 36 | - nsg_config_enum 37 | #change compute.tf and move custom_image_id to Compute group in case you want to use a custom_image 38 | - custom_image_id 39 | - marketplace_source_images 40 | 41 | - title: "Compute Configuration" 42 | variables: 43 | - compute_compartment_ocid 44 | - vm_display_name 45 | - hostname_label 46 | - vm_compute_shape 47 | - vm_flex_shape_ocpus 48 | - availability_domain_name 49 | - ssh_public_key 50 | 51 | 52 | - title: "Virtual Cloud Network" 53 | variables: 54 | - network_compartment_ocid 55 | - network_strategy 56 | - network_configuration_strategy 57 | - vcn_id 58 | - vcn_display_name 59 | - vcn_dns_label 60 | - vcn_cidr_block 61 | 62 | - title: "Simple Subnet" 63 | visible: #($network_strategy == ""Use Existing VCN and Subnet"") OR (network_configuration_strategy == "Customize Network Configuration") 64 | or: 65 | - eq: 66 | - network_strategy 67 | - "Use Existing VCN and Subnet" 68 | - eq: 69 | - network_configuration_strategy 70 | - "Customize Network Configuration" 71 | variables: 72 | - subnet_type 73 | - subnet_id 74 | - subnet_display_name 75 | - subnet_dns_label 76 | - subnet_cidr_block 77 | - nsg_configuration_strategy 78 | 79 | - title: "Network Security Group" 80 | visible: #($nsg_configuration_strategy == "Customize Network Security Group") 81 | eq: 82 | - nsg_configuration_strategy 83 | - "Customize Network Security Group" 84 | variables: 85 | - nsg_display_name 86 | - nsg_source_cidr 87 | - nsg_ssh_port 88 | - nsg_http_port 89 | - nsg_https_port 90 | 91 | - title: "Additional Configuration Options" 92 | variables: 93 | - tag_key_name 94 | - tag_value 95 | 96 | 97 | ###################################################### 98 | ############## VARIABLES ############# 99 | ###################################################### 100 | 101 | variables: 102 | # Hidden variables 103 | 104 | ###################################################### 105 | ############## HIDDEN VARIABLES ############# 106 | ###################################################### 107 | 108 | 109 | tenancy_ocid: 110 | type: string 111 | title: Tenancy ID 112 | description: The Oracle Cloud Identifier (OCID) for your tenancy 113 | required: true 114 | 115 | region: 116 | type: oci:identity:region:name 117 | title: Region 118 | description: The region in which to create all resources 119 | required: true 120 | 121 | availability_domain_number: 122 | type: string 123 | required: false 124 | description: Availability Domain Number (Not used) 125 | 126 | ###################################################### 127 | ############## MARKETPLACE VARIABLES ############# 128 | ###################################################### 129 | 130 | mp_listing_id: 131 | type: string 132 | required: true 133 | description: Marketplace Listing ID 134 | 135 | mp_listing_resource_id: 136 | type: oci:core:image:id 137 | required: true 138 | description: Marketplace Image OCID 139 | dependsOn: 140 | compartmentId: compute_compartment_ocid 141 | 142 | mp_listing_resource_version: 143 | type: string 144 | required: true 145 | description: Marketplace Listing package version 146 | 147 | 148 | mp_subscription_enabled: 149 | type: boolean 150 | title: Use Marketplace Image? 151 | default: false 152 | 153 | custom_image_id: 154 | type: string 155 | required: true 156 | title: Custom Image OCID 157 | # visible: 158 | # eq: 159 | # - mp_subscription_enabled 160 | # - false 161 | 162 | 163 | tag_key_name: 164 | type: string 165 | required: true 166 | title: Tag key name 167 | 168 | tag_value: 169 | type: string 170 | required: true 171 | title: Tag value 172 | 173 | 174 | ###################################################### 175 | ############## COMPUTE VARIABLES ############# 176 | ###################################################### 177 | 178 | compute_compartment_ocid: 179 | type: oci:identity:compartment:id 180 | required: true 181 | title: Compute Compartment 182 | description: The compartment in which to create all Compute resources 183 | default: compartment_ocid 184 | 185 | availability_domain_name: 186 | type: oci:identity:availabilitydomain:name 187 | dependsOn: 188 | compartmentId: compute_compartment_ocid 189 | required: true 190 | default: 1 191 | title: Availability Domain 192 | description: Availability Domain 193 | 194 | ssh_public_key: 195 | type: oci:core:ssh:publickey 196 | required: true 197 | title: Public SSH Key string 198 | description: Public SSH Key to access VM via SSH 199 | 200 | vm_display_name: 201 | type: string 202 | required: true 203 | title: Instance Name 204 | description: The name of the Instance 205 | 206 | vm_compute_shape: 207 | type: oci:core:instanceshape:name 208 | default: VM.Standard2.2 209 | title: Compute Shape 210 | required: true 211 | dependsOn: 212 | compartmentId: compute_compartment_ocid 213 | #Comment in to restrict to marketplace image allowed shapes 214 | #imageId: mp_listing_resource_id 215 | 216 | vm_flex_shape_ocpus: 217 | visible: #($vm_compute_shape == ""VM.Standard.E3.Flex"") 218 | eq: 219 | - vm_compute_shape 220 | - "VM.Standard.E3.Flex" 221 | type: integer 222 | default: 2 223 | title: Flex Shape OCPUs 224 | minimum: 1 225 | maximum: 64 226 | required: false 227 | 228 | hostname_label: 229 | type: string 230 | required: false 231 | title: DNS Hostname Label 232 | 233 | 234 | ###################################################### 235 | ############## NETWORK VARIABLES ############# 236 | ###################################################### 237 | 238 | network_compartment_ocid: 239 | type: oci:identity:compartment:id 240 | required: true 241 | title: Network Compartment 242 | description: The compartment in which to create all Network resources 243 | default: compartment_ocid 244 | 245 | 246 | # Network Type Options 247 | network_strategy: 248 | type: enum 249 | title: Network Strategy 250 | description: Create or use existing Network Stack (VCN and Subnet) 251 | enum: 252 | - "Create New VCN and Subnet" 253 | - "Use Existing VCN and Subnet" 254 | required: true 255 | default: "Create New VCN and Subnet" 256 | 257 | 258 | # Network Configuration 259 | network_configuration_strategy: 260 | visible: #($network_strategy == ""Create New VCN and Subnet"") 261 | eq: 262 | - network_strategy 263 | - "Create New VCN and Subnet" 264 | type: enum 265 | title: Configuration Strategy 266 | description: Use recommended configuration or customize it 267 | enum: 268 | - "Use Recommended Configuration" 269 | - "Customize Network Configuration" 270 | required: true 271 | default: "Use Recommended Configuration" 272 | 273 | 274 | 275 | ######## VCN ######## 276 | 277 | vcn_display_name: 278 | visible: #($network_strategy == ""Create New VCN and Subnet"") AND (network_configuration_strategy == "Customize Network Configuration") 279 | and: 280 | - eq: 281 | - network_strategy 282 | - "Create New VCN and Subnet" 283 | - eq: 284 | - network_configuration_strategy 285 | - "Customize Network Configuration" 286 | type: string 287 | required: true 288 | title: Name 289 | description: The name of the new Virtual Cloud Network (VCN) 290 | 291 | vcn_id: 292 | visible: #($network_strategy == "Use Existing VCN and Subnet") 293 | eq: 294 | - network_strategy 295 | - "Use Existing VCN and Subnet" 296 | type: oci:core:vcn:id 297 | dependsOn: 298 | compartmentId: network_compartment_ocid 299 | required: true 300 | title: Existing VCN 301 | description: An existing Virtual Cloud Network (VCN) in which to create the compute instances, network resources, and load balancers. If not specified, a new VCN is created. 302 | 303 | vcn_cidr_block: 304 | visible: #($network_strategy == ""Create New VCN and Subnet"") AND (network_configuration_strategy == "Customize Network Configuration") 305 | and: 306 | - eq: 307 | - network_strategy 308 | - "Create New VCN and Subnet" 309 | - eq: 310 | - network_configuration_strategy 311 | - "Customize Network Configuration" 312 | type: string 313 | required: true 314 | pattern: "^(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9]).(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9]).(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9]).(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\\/(3[0-2]|[1-2]?[0-9])$" 315 | title: CIDR Block 316 | description: The CIDR of the new Virtual Cloud Network (VCN). If you plan to peer this VCN with another VCN, the VCNs must not have overlapping CIDRs. 317 | 318 | vcn_dns_label: 319 | visible: #($network_strategy == ""Create New VCN and Subnet"") AND (network_configuration_strategy == "Customize Network Configuration") 320 | and: 321 | - eq: 322 | - network_strategy 323 | - "Create New VCN and Subnet" 324 | - eq: 325 | - network_configuration_strategy 326 | - "Customize Network Configuration" 327 | type: string 328 | required: true 329 | title: DNS Label 330 | maxLenght: 15 331 | description: VCN DNS Label. Only letters and numbers, starting with a letter. 15 characters max. 332 | 333 | ######## MANAGEMENT SUBNET ######## 334 | subnet_type: 335 | visible: #($network_strategy == ""Create New VCN and Subnet"") 336 | eq: 337 | - network_strategy 338 | - "Create New VCN and Subnet" 339 | type: enum 340 | title: Subnet Type 341 | description: Choose between private and public subnets 342 | enum: 343 | - "Private Subnet" 344 | - "Public Subnet" 345 | required: true 346 | default: "Public Subnet" 347 | 348 | subnet_display_name: 349 | visible: #($network_strategy == ""Create New VCN and Subnet"") 350 | eq: 351 | - network_strategy 352 | - "Create New VCN and Subnet" 353 | type: string 354 | required: true 355 | title: Name 356 | description: The name of the new Subnet 357 | 358 | subnet_cidr_block: 359 | visible: #($network_strategy == ""Create New VCN and Subnet"") 360 | eq: 361 | - network_strategy 362 | - "Create New VCN and Subnet" 363 | type: string 364 | pattern: "^(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9]).(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9]).(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9]).(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\\/(3[0-2]|[1-2]?[0-9])$" 365 | required: true 366 | title: CIDR Block 367 | description: The CIDR of the new Subnet. The new subnet's CIDR should not overlap with any other subnet CIDRs. 368 | 369 | subnet_id: 370 | visible: #($network_strategy == "Use Existing VCN and Subnet") 371 | eq: 372 | - network_strategy 373 | - "Use Existing VCN and Subnet" 374 | type: oci:core:subnet:id 375 | dependsOn: 376 | vcnId: vcn_id 377 | compartmentId: network_compartment_ocid 378 | default: '' 379 | required: true 380 | title: Existing Subnet 381 | description: An existing Management subnet. This subnet must already be present in the chosen VCN. 382 | 383 | subnet_dns_label: 384 | visible: #($network_strategy == ""Create New VCN and Subnet"") 385 | eq: 386 | - network_strategy 387 | - "Create New VCN and Subnet" 388 | type: string 389 | required: true 390 | title: DNS Label 391 | maxLenght: 15 392 | description: Subnet DNS Label. Only letters and numbers, starting with a letter. 15 characters max. 393 | 394 | ###################################################### 395 | ############## SECURITY VARIABLES ############# 396 | ###################################################### 397 | 398 | 399 | nsg_configuration_strategy: 400 | visible: true 401 | type: enum 402 | title: Network Security Group Configuration 403 | description: Choose Network Security Rules Strategy 404 | enum: 405 | - "Use Recommended Configuration" 406 | - "Customize Network Security Group" 407 | required: true 408 | default: "Use Recommended Configuration" 409 | 410 | 411 | nsg_display_name: 412 | type: string 413 | required: false 414 | title: Name 415 | 416 | nsg_ssh_port: 417 | type: number 418 | required: false 419 | default: 22 420 | title: SSH Port Number 421 | 422 | nsg_http_port: 423 | type: number 424 | required: false 425 | default: 80 426 | title: HTTP Port Number 427 | 428 | nsg_https_port: 429 | type: number 430 | required: false 431 | default: 443 432 | title: HTTPS Port Number 433 | 434 | nsg_source_cidr: 435 | type: string 436 | required: false 437 | default: "0.0.0.0/0" 438 | title: Allowed Ingress Traffic (CIDR Block) 439 | 440 | 441 | 442 | 443 | ############################################# 444 | ########### OUTPUT GROUPS ############ 445 | ############################################# 446 | 447 | outputGroups: 448 | - title: "Instance Management" 449 | outputs: 450 | - instance_public_ip 451 | - instance_private_ip 452 | 453 | 454 | ############################################# 455 | ############## OUTPUTS ############## 456 | ############################################# 457 | 458 | outputs: 459 | instance_https_url: 460 | type: link 461 | title: Open Application URL 462 | visible: false 463 | 464 | instance_public_ip: 465 | type: link 466 | title: Public IP 467 | visible: #($mgmt_subnet_type == "Public Subnet") 468 | eq: 469 | - mgmt_subnet_type 470 | - "Public Subnet" 471 | 472 | instance_private_ip: 473 | type: link 474 | title: Private IP 475 | visible: true 476 | 477 | primaryOutputButton: instance_https_url 478 | -------------------------------------------------------------------------------- /scripts/example.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | touch ~opc/hello_world 4 | -------------------------------------------------------------------------------- /terraform.tfvars.template: -------------------------------------------------------------------------------- 1 | user_ocid = "ocid1.user.oc1.." 2 | fingerprint = "1c.." 3 | private_key_path = "~/.oci/oci_api_key.pem" 4 | tenancy_ocid = "ocid1.tenancy.oc1.." 5 | region = "us-ashburn-1" 6 | 7 | compute_compartment_ocid = "ocid1.compartment.oc1." 8 | network_compartment_ocid = "ocid1.compartment.oc1." 9 | availability_domain_number = "1" 10 | ssh_public_key = "ssh-rsa AAA...H" -------------------------------------------------------------------------------- /variables.tf: -------------------------------------------------------------------------------- 1 | #Variables declared in this file must be declared in the marketplace.yaml 2 | #Provide a description to your variables. 3 | 4 | ############################ 5 | # Hidden Variable Group # 6 | ############################ 7 | variable "tenancy_ocid" { 8 | } 9 | 10 | variable "region" { 11 | } 12 | 13 | ############################################################################### 14 | # Marketplace Image Listing - information available in the Partner portal # 15 | ############################################################################### 16 | variable "mp_subscription_enabled" { 17 | description = "Subscribe to Marketplace listing?" 18 | type = bool 19 | default = false 20 | } 21 | 22 | variable "mp_listing_id" { 23 | // default = "ocid1.appcataloglisting.oc1.." 24 | default = "" 25 | description = "Marketplace Listing OCID" 26 | } 27 | 28 | variable "mp_listing_resource_id" { 29 | // default = "ocid1.image.oc1.." 30 | default = "" 31 | description = "Marketplace Listing Image OCID" 32 | } 33 | 34 | variable "mp_listing_resource_version" { 35 | // default = "1.0" 36 | default = "" 37 | description = "Marketplace Listing Package/Resource Version" 38 | } 39 | 40 | ############################ 41 | # Custom Image # 42 | ############################ 43 | variable "custom_image_id" { 44 | default = "ocid1.image.oc1...." 45 | description = "Custom Image OCID" 46 | } 47 | 48 | ############################ 49 | # Compute Configuration # 50 | ############################ 51 | 52 | variable "vm_display_name" { 53 | description = "Instance Name" 54 | default = "simple-vm" 55 | } 56 | 57 | variable "vm_compute_shape" { 58 | description = "Compute Shape" 59 | default = "VM.Standard2.2" //2 cores 60 | } 61 | 62 | # only used for E3 Flex shape 63 | variable "vm_flex_shape_ocpus" { 64 | description = "Flex Shape OCPUs" 65 | default = 1 66 | } 67 | 68 | variable "availability_domain_name" { 69 | default = "" 70 | description = "Availability Domain name, if non-empty takes precedence over availability_domain_number" 71 | } 72 | 73 | variable "availability_domain_number" { 74 | default = 1 75 | description = "OCI Availability Domains: 1,2,3 (subject to region availability)" 76 | } 77 | 78 | variable "ssh_public_key" { 79 | description = "SSH Public Key" 80 | } 81 | 82 | variable "hostname_label" { 83 | default = "simple" 84 | description = "DNS Hostname Label. Must be unique across all VNICs in the subnet and comply with RFC 952 and RFC 1123." 85 | } 86 | 87 | ############################ 88 | # Network Configuration # 89 | ############################ 90 | 91 | variable "network_strategy" { 92 | #default = "Use Existing VCN and Subnet" 93 | default = "Create New VCN and Subnet" 94 | } 95 | 96 | variable "vcn_id" { 97 | default = "" 98 | } 99 | 100 | variable "vcn_display_name" { 101 | description = "VCN Name" 102 | default = "simple-vcn" 103 | } 104 | 105 | variable "vcn_cidr_block" { 106 | description = "VCN CIDR" 107 | default = "10.0.0.0/16" 108 | } 109 | 110 | variable "vcn_dns_label" { 111 | description = "VCN DNS Label" 112 | default = "simplevcn" 113 | } 114 | 115 | variable "subnet_type" { 116 | description = "Choose between private and public subnets" 117 | default = "Public Subnet" 118 | #or 119 | #default = "Private Subnet" 120 | } 121 | 122 | variable "subnet_id" { 123 | default = "" 124 | } 125 | 126 | variable "subnet_display_name" { 127 | description = "Subnet Name" 128 | default = "simple-subnet" 129 | } 130 | 131 | variable "subnet_cidr_block" { 132 | description = "Subnet CIDR" 133 | default = "10.0.0.0/24" 134 | } 135 | 136 | variable "subnet_dns_label" { 137 | description = "Subnet DNS Label" 138 | default = "simplesubnet" 139 | } 140 | 141 | ############################ 142 | # Security Configuration # 143 | ############################ 144 | variable "nsg_display_name" { 145 | description = "Network Security Group Name" 146 | default = "simple-network-security-group" 147 | } 148 | 149 | variable "nsg_source_cidr" { 150 | description = "Allowed Ingress Traffic (CIDR Block)" 151 | default = "0.0.0.0/0" 152 | } 153 | 154 | variable "nsg_ssh_port" { 155 | description = "SSH Port" 156 | default = 22 157 | } 158 | 159 | variable "nsg_https_port" { 160 | description = "HTTPS Port" 161 | default = 443 162 | } 163 | 164 | variable "nsg_http_port" { 165 | description = "HTTP Port" 166 | default = 80 167 | } 168 | 169 | ############################ 170 | # Additional Configuration # 171 | ############################ 172 | 173 | variable "compartment_ocid" { 174 | description = "Compartment where Compute and Marketplace subscription resources will be created" 175 | } 176 | 177 | variable "tag_key_name" { 178 | description = "Free-form tag key name" 179 | default = "oracle-quickstart" 180 | } 181 | 182 | variable "tag_value" { 183 | description = "Free-form tag value" 184 | default = "oci-quickstart-template" 185 | } 186 | 187 | 188 | ###################### 189 | # Enum Values # 190 | ###################### 191 | variable "network_strategy_enum" { 192 | type = map 193 | default = { 194 | CREATE_NEW_VCN_SUBNET = "Create New VCN and Subnet" 195 | USE_EXISTING_VCN_SUBNET = "Use Existing VCN and Subnet" 196 | } 197 | } 198 | 199 | variable "subnet_type_enum" { 200 | type = map 201 | default = { 202 | PRIVATE_SUBNET = "Private Subnet" 203 | PUBLIC_SUBNET = "Public Subnet" 204 | } 205 | } 206 | 207 | variable "nsg_config_enum" { 208 | type = map 209 | default = { 210 | BLOCK_ALL_PORTS = "Block all ports" 211 | OPEN_ALL_PORTS = "Open all ports" 212 | CUSTOMIZE = "Customize ports - Post deployment" 213 | } 214 | } 215 | -------------------------------------------------------------------------------- /versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 1.5.0" 3 | required_providers { 4 | oci = { 5 | source = "oracle/oci" 6 | version =">= 6.30" 7 | } 8 | } 9 | } 10 | --------------------------------------------------------------------------------