Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: is snapshots #2672

Merged
merged 1 commit into from
Jul 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
129 changes: 117 additions & 12 deletions examples/ibm-is-ng/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,15 @@ resource "ibm_is_instance_template" "instancetemplate1" {
name = "testbootvol"
delete_volume_on_instance_delete = true
}
volume_attachments {
delete_volume_on_instance_delete = true
name = "volatt-01"
volume_prototype {
iops = 3000
profile = "general-purpose"
capacity = 200
}
}
volume_attachments {
delete_volume_on_instance_delete = true
name = "volatt-01"
volume_prototype {
iops = 3000
profile = "general-purpose"
capacity = 200
}
}
uibm marked this conversation as resolved.
Show resolved Hide resolved
}

resource "ibm_is_instance_template" "instancetemplate2" {
Expand Down Expand Up @@ -432,15 +432,120 @@ data "ibm_is_dedicated_host" "dhost" {
host_group = data.ibm_is_dedicated_host_group.dgroup.id
}

resource "ibm_is_volume" "vol3" {
name = "vol3"
profile = "10iops-tier"
zone = var.zone1
}

// creating an instance with volumes
resource "ibm_is_instance" "instance4" {
name = "instance4"
image = var.image
profile = var.profile

volumes = [ ibm_is_volume.vol3.id ]

primary_network_interface {
subnet = ibm_is_subnet.subnet1.id
}

vpc = ibm_is_vpc.vpc1.id
zone = var.zone1
keys = [ibm_is_ssh_key.sshkey.id]
}

// creating a snapshot from boot volume
resource "ibm_is_snapshot" "b_snapshot" {
name = "my-snapshot-boot"
source_volume = ibm_is_instance.instance4.volume_attachments[0].volume_id
}

// creating a snapshot from data volume
resource "ibm_is_snapshot" "d_snapshot" {
name = "my-snapshot-data"
source_volume = ibm_is_instance.instance4.volume_attachments[1].volume_id
}

// data source for snapshot by name
data "ibm_is_snapshot" "ds_snapshot" {
name = "my-snapshot-boot"
}

// data source for snapshots
data "ibm_is_snapshots" "ds_snapshots" {
}

// restoring a boot volume from snapshot in a new instance
resource "ibm_is_instance" "instance5" {
name = "instance5"
profile = var.profile
boot_volume {
name = "boot-restore"
uibm marked this conversation as resolved.
Show resolved Hide resolved
snapshot = ibm_is_snapshot.b_snapshot.id
}
auto_delete_volume = true
primary_network_interface {
subnet = ibm_is_subnet.subnet2.id
}
vpc = ibm_is_vpc.vpc2.id
zone = "us-south-2"
keys = [ibm_is_ssh_key.sshkey.id]
}

// creating a volume
resource "ibm_is_volume" "vol5" {
name = "vol5"
profile = "10iops-tier"
zone = "us-south-2"
}

// creating a volume attachment on an existing instance using an existing volume
resource "ibm_is_instance_volume_attachment" "att1" {
instance = ibm_is_instance.instance5.id
volume = ibm_is_volume.vol5.id
name = "vol-att-1"
delete_volume_on_attachment_delete = false
delete_volume_on_instance_delete = false
}

// creating a volume attachment on an existing instance using a new volume
resource "ibm_is_instance_volume_attachment" "att2" {
instance = ibm_is_instance.instance5.id
name = "vol-att-2"
profile = "general-purpose"
snapshot = ibm_is_snapshot.d_snapshot.id
delete_volume_on_instance_delete = true
delete_volume_on_attachment_delete = true
volume_name = "vol4-restore"
}

// data source for volume attachment
data "ibm_is_instance_volume_attachment" "ds_vol_att" {
instance = ibm_is_instance.instance5.id
name = ibm_is_instance_volume_attachment.att2.name
}

// data source for volume attachments
data "ibm_is_instance_volume_attachment" "ds_vol_atts" {
instance = ibm_is_instance.instance5.id
}

// creating an instance using an existing instance template
resource "ibm_is_instance" "instance6" {
name = "instance4"
instance_template = ibm_is_instance_template.instancetemplate1.id
}

resource "ibm_is_image" "image1" {
href = var.image_cos_url
name = "my-img-1"
href = var.image_cos_url
name = "my-img-1"
operating_system = var.image_operating_system
}

resource "ibm_is_image" "image2" {
source_volume = data.ibm_is_instance.instance1.volume_attachments.0.volume_id
name = "my-img-1"
name = "my-img-1"
}

data "ibm_is_image" "dsimage" {
Expand Down
168 changes: 168 additions & 0 deletions ibm/data_source_ibm_is_instance_volume_attachment.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
// Copyright IBM Corp. 2017, 2021 All Rights Reserved.
// Licensed under the Mozilla Public License v2.0

package ibm

import (
"fmt"

"github.com/IBM/vpc-go-sdk/vpcv1"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

const (
isInstanceVolumeAttDevice = "device"
isInstanceVolumeAttHref = "href"
isInstanceVolumeAttStatus = "status"
isInstanceVolumeAttType = "type"
isInstanceVolumeAttVolumeReference = "volume_reference"
isInstanceVolumeAttVolumeReferenceCrn = "volume_crn"
isInstanceVolumeAttVolumeReferenceDeleted = "volume_deleted"
isInstanceVolumeAttVolumeReferenceHref = "volume_href"
isInstanceVolumeAttVolumeReferenceId = "volume_id"
isInstanceVolumeAttVolumeReferenceName = "volume_name"
)

func dataSourceIBMISInstanceVolumeAttachment() *schema.Resource {
return &schema.Resource{
Read: dataSourceIBMISInstanceVolumeAttachmentRead,

Schema: map[string]*schema.Schema{

isInstanceId: {
Type: schema.TypeString,
Required: true,
Description: "Instance id",
},
isInstanceVolAttName: {
Type: schema.TypeString,
Required: true,
Description: "The user-defined name for this volume attachment.",
},

isInstanceVolumeDeleteOnInstanceDelete: {
uibm marked this conversation as resolved.
Show resolved Hide resolved
Type: schema.TypeBool,
Computed: true,
Description: "If set to true, when deleting the instance the volume will also be deleted.",
},

isInstanceVolumeAttDevice: {
Type: schema.TypeString,
Computed: true,
Description: "A unique identifier for the device which is exposed to the instance operating system",
},

isInstanceVolumeAttHref: {
Type: schema.TypeString,
Computed: true,
Description: "The URL for this volume attachment",
},

isInstanceVolAttId: {
Type: schema.TypeString,
Computed: true,
Description: "The unique identifier for this volume attachment",
},

isInstanceVolumeAttStatus: {
Type: schema.TypeString,
Computed: true,
Description: "The status of this volume attachment, one of [ attached, attaching, deleting, detaching ]",
},

isInstanceVolumeAttType: {
Type: schema.TypeString,
Computed: true,
Description: "The type of volume attachment one of [ boot, data ]",
},

isInstanceVolumeAttVolumeReference: {
Type: schema.TypeList,
Computed: true,
Description: "The attached volume",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
isInstanceVolumeAttVolumeReferenceId: {
Type: schema.TypeString,
Computed: true,
Description: "The unique identifier for this volume",
},
isInstanceVolumeAttVolumeReferenceName: {
Type: schema.TypeString,
Computed: true,
Description: "The unique user-defined name for this volume",
},
isInstanceVolumeAttVolumeReferenceCrn: {
Type: schema.TypeString,
Computed: true,
Description: "The CRN for this volume",
},
isInstanceVolumeAttVolumeReferenceDeleted: {
Type: schema.TypeString,
Computed: true,
Description: "Link to documentation about deleted resources",
},
isInstanceVolumeAttVolumeReferenceHref: {
Type: schema.TypeString,
Computed: true,
Description: "The URL for this volume",
},
},
},
},
},
}
}

func dataSourceIBMISInstanceVolumeAttachmentRead(d *schema.ResourceData, meta interface{}) error {
instanceId := d.Get(isInstanceId).(string)
name := d.Get(isInstanceName).(string)
err := instanceVolumeAttachmentGetByName(d, meta, instanceId, name)
if err != nil {
return err
}
return nil
}

func instanceVolumeAttachmentGetByName(d *schema.ResourceData, meta interface{}, instanceId, name string) error {
sess, err := vpcClient(meta)
if err != nil {
return err
}
allrecs := []vpcv1.VolumeAttachment{}
listInstanceVolumeAttOptions := &vpcv1.ListInstanceVolumeAttachmentsOptions{
InstanceID: &instanceId,
}
volumeAtts, response, err := sess.ListInstanceVolumeAttachments(listInstanceVolumeAttOptions)
if err != nil {
return fmt.Errorf("Error fetching Instance volume attachments %s\n%s", err, response)
}
allrecs = append(allrecs, volumeAtts.VolumeAttachments...)
for _, volumeAtt := range allrecs {
if *volumeAtt.Name == name {
d.SetId(makeTerraformVolAttID(instanceId, *volumeAtt.ID))
d.Set(isInstanceVolAttName, *volumeAtt.Name)
d.Set(isInstanceVolumeDeleteOnInstanceDelete, *volumeAtt.DeleteVolumeOnInstanceDelete)
d.Set(isInstanceVolumeAttDevice, *volumeAtt.Device.ID)
d.Set(isInstanceVolumeAttHref, *volumeAtt.Href)
d.Set(isInstanceVolAttId, *volumeAtt.ID)
d.Set(isInstanceVolumeAttStatus, *volumeAtt.Status)
d.Set(isInstanceVolumeAttType, *volumeAtt.Type)
volList := make([]map[string]interface{}, 0)
if volumeAtt.Volume != nil {
currentVol := map[string]interface{}{}
currentVol[isInstanceVolumeAttVolumeReferenceId] = *volumeAtt.Volume.ID
currentVol[isInstanceVolumeAttVolumeReferenceName] = *volumeAtt.Volume.Name
currentVol[isInstanceVolumeAttVolumeReferenceCrn] = *volumeAtt.Volume.CRN
if volumeAtt.Volume.Deleted != nil {
currentVol[isInstanceVolumeAttVolumeReferenceDeleted] = *volumeAtt.Volume.Deleted.MoreInfo
}
currentVol[isInstanceVolumeAttVolumeReferenceHref] = *volumeAtt.Volume.Href
volList = append(volList, currentVol)
}
d.Set(isInstanceVolumeAttVolumeReference, volList)
return nil
}
}
return fmt.Errorf("No Instance volume attachment found with name %s on instance %s", name, instanceId)
}
Loading