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

azurerm_container_group - add support for volume.x.git_repo #7924

Merged
merged 3 commits into from
Oct 26, 2020
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
114 changes: 102 additions & 12 deletions azurerm/internal/services/containers/container_group_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -325,25 +325,53 @@ func resourceArmContainerGroup() *schema.Resource {

"share_name": {
Type: schema.TypeString,
Required: true,
Optional: true,
ForceNew: true,
ValidateFunc: validation.StringIsNotEmpty,
},

"storage_account_name": {
Type: schema.TypeString,
Required: true,
Optional: true,
ForceNew: true,
ValidateFunc: validation.StringIsNotEmpty,
},

"storage_account_key": {
Type: schema.TypeString,
Required: true,
Optional: true,
Sensitive: true,
ForceNew: true,
ValidateFunc: validation.StringIsNotEmpty,
},

"git_repo": {
Type: schema.TypeList,
Optional: true,
ForceNew: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"url": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},

"directory": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},

"revision": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
},
},
},
},
},
},
Expand Down Expand Up @@ -488,7 +516,10 @@ func resourceArmContainerGroupCreate(d *schema.ResourceData, meta interface{}) e
diagnosticsRaw := d.Get("diagnostics").([]interface{})
diagnostics := expandContainerGroupDiagnostics(diagnosticsRaw)
dnsConfig := d.Get("dns_config").([]interface{})
containers, containerGroupPorts, containerGroupVolumes := expandContainerGroupContainers(d)
containers, containerGroupPorts, containerGroupVolumes, err := expandContainerGroupContainers(d)
if err != nil {
return err
}
containerGroup := containerinstance.ContainerGroup{
Name: &name,
Location: &location,
Expand Down Expand Up @@ -726,7 +757,7 @@ func containerGroupEnsureDetachedFromNetworkProfileRefreshFunc(ctx context.Conte
}
}

func expandContainerGroupContainers(d *schema.ResourceData) (*[]containerinstance.Container, *[]containerinstance.Port, *[]containerinstance.Volume) {
func expandContainerGroupContainers(d *schema.ResourceData) (*[]containerinstance.Container, *[]containerinstance.Port, *[]containerinstance.Volume, error) {
containersConfig := d.Get("container").([]interface{})
containers := make([]containerinstance.Container, 0)
containerGroupPorts := make([]containerinstance.Port, 0)
Expand Down Expand Up @@ -819,7 +850,10 @@ func expandContainerGroupContainers(d *schema.ResourceData) (*[]containerinstanc
}

if v, ok := data["volume"]; ok {
volumeMounts, containerGroupVolumesPartial := expandContainerVolumes(v)
volumeMounts, containerGroupVolumesPartial, err := expandContainerVolumes(v)
if err != nil {
return nil, nil, nil, err
}
container.VolumeMounts = volumeMounts
if containerGroupVolumesPartial != nil {
containerGroupVolumes = append(containerGroupVolumes, *containerGroupVolumesPartial...)
Expand All @@ -837,7 +871,7 @@ func expandContainerGroupContainers(d *schema.ResourceData) (*[]containerinstanc
containers = append(containers, container)
}

return &containers, &containerGroupPorts, &containerGroupVolumes
return &containers, &containerGroupPorts, &containerGroupVolumes, nil
}

func expandContainerEnvironmentVariables(input interface{}, secure bool) *[]containerinstance.EnvironmentVariable {
Expand Down Expand Up @@ -912,11 +946,11 @@ func expandContainerImageRegistryCredentials(d *schema.ResourceData) *[]containe
return &output
}

func expandContainerVolumes(input interface{}) (*[]containerinstance.VolumeMount, *[]containerinstance.Volume) {
func expandContainerVolumes(input interface{}) (*[]containerinstance.VolumeMount, *[]containerinstance.Volume, error) {
volumesRaw := input.([]interface{})

if len(volumesRaw) == 0 {
return nil, nil
return nil, nil, nil
}

volumeMounts := make([]containerinstance.VolumeMount, 0)
Expand All @@ -942,18 +976,49 @@ func expandContainerVolumes(input interface{}) (*[]containerinstance.VolumeMount

cv := containerinstance.Volume{
Name: utils.String(name),
AzureFile: &containerinstance.AzureFileVolume{
}

gitRepoVolume := expandGitRepoVolume(volumeConfig["git_repo"].([]interface{}))
if gitRepoVolume != nil {
if shareName != "" || storageAccountName != "" || storageAccountKey != "" {
return nil, nil, fmt.Errorf("only one of `git_repo` volume or `share_name`, `storage_account_name`, and `storage_account_key` can be specified")
}
cv.GitRepo = gitRepoVolume
} else {
if shareName == "" && storageAccountName == "" && storageAccountKey == "" {
return nil, nil, fmt.Errorf("one of `git_repo` or `share_name`, `storage_account_name`, and `storage_account_key` must be specified")
} else if shareName == "" || storageAccountName == "" || storageAccountKey == "" {
return nil, nil, fmt.Errorf("when using a storage account volume, all of `share_name`, `storage_account_name`, `storage_account_key` must be specified")
}
cv.AzureFile = &containerinstance.AzureFileVolume{
ShareName: utils.String(shareName),
ReadOnly: utils.Bool(readOnly),
StorageAccountName: utils.String(storageAccountName),
StorageAccountKey: utils.String(storageAccountKey),
},
}
}

containerGroupVolumes = append(containerGroupVolumes, cv)
}

return &volumeMounts, &containerGroupVolumes
return &volumeMounts, &containerGroupVolumes, nil
}

func expandGitRepoVolume(input []interface{}) *containerinstance.GitRepoVolume {
if len(input) == 0 || input[0] == nil {
return nil
}
v := input[0].(map[string]interface{})
gitRepoVolume := &containerinstance.GitRepoVolume{
Repository: utils.String(v["url"].(string)),
}
if directory := v["directory"].(string); directory != "" {
gitRepoVolume.Directory = utils.String(directory)
}
if revision := v["revision"].(string); revision != "" {
gitRepoVolume.Revision = utils.String(revision)
}
return gitRepoVolume
}

func expandContainerProbe(input interface{}) *containerinstance.ContainerProbe {
Expand Down Expand Up @@ -1243,6 +1308,8 @@ func flattenContainerVolumes(volumeMounts *[]containerinstance.VolumeMount, cont
}
// skip storage_account_key, is always nil
}

volumeConfig["git_repo"] = flattenGitRepoVolume(cgv.GitRepo)
}
}
}
Expand All @@ -1266,6 +1333,29 @@ func flattenContainerVolumes(volumeMounts *[]containerinstance.VolumeMount, cont
return volumeConfigs
}

func flattenGitRepoVolume(input *containerinstance.GitRepoVolume) []interface{} {
if input == nil {
return []interface{}{}
}
var revision, directory, repository string
if input.Directory != nil {
directory = *input.Directory
}
if input.Revision != nil {
revision = *input.Revision
}
if input.Repository != nil {
repository = *input.Repository
}
return []interface{}{
map[string]interface{}{
"url": repository,
"directory": directory,
"revision": revision,
},
}
}

func flattenContainerProbes(input *containerinstance.ContainerProbe) []interface{} {
outputs := make([]interface{}, 0)
if input == nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,25 @@ func TestAccAzureRMContainerGroup_withPrivateEmpty(t *testing.T) {
})
}

func TestAccAzureRMContainerGroup_gitRepoVolume(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_container_group", "test")

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acceptance.PreCheck(t) },
Providers: acceptance.SupportedProviders,
CheckDestroy: testCheckAzureRMContainerGroupDestroy,
Steps: []resource.TestStep{
{
Config: testAccAzureRMContainerGroup_gitRepoVolume(data),
Check: resource.ComposeTestCheckFunc(
testCheckAzureRMContainerGroupExists(data.ResourceName),
),
},
data.ImportStep(),
},
})
}

func testAccAzureRMContainerGroup_SystemAssignedIdentity(data acceptance.TestData) string {
return fmt.Sprintf(`
provider "azurerm" {
Expand Down Expand Up @@ -1213,6 +1232,83 @@ resource "azurerm_container_group" "test" {
`, data.RandomInteger, data.Locations.Primary, data.RandomInteger, data.RandomInteger, data.RandomInteger, data.RandomInteger, data.RandomInteger)
}

func testAccAzureRMContainerGroup_gitRepoVolume(data acceptance.TestData) string {
return fmt.Sprintf(`
provider "azurerm" {
features {}
}

resource "azurerm_resource_group" "test" {
name = "acctestRG-%d"
location = "%s"
}

resource "azurerm_container_group" "test" {
name = "acctestcontainergroup-%d"
location = "${azurerm_resource_group.test.location}"
resource_group_name = "${azurerm_resource_group.test.name}"
ip_address_type = "public"
dns_name_label = "acctestcontainergroup-%d"
os_type = "Linux"
restart_policy = "OnFailure"

container {
name = "hf"
image = "seanmckenna/aci-hellofiles"
cpu = "1"
memory = "1.5"

ports {
port = 80
protocol = "TCP"
}

volume {
name = "logs"
mount_path = "/aci/logs"
read_only = false

git_repo {
url = "https://github.com/Azure-Samples/aci-helloworld"
directory = "app"
revision = "d5ccfce"
}
}

environment_variables = {
foo = "bar"
foo1 = "bar1"
}

readiness_probe {
exec = ["cat", "/tmp/healthy"]
initial_delay_seconds = 1
period_seconds = 1
failure_threshold = 1
success_threshold = 1
timeout_seconds = 1
}

liveness_probe {
http_get {
path = "/"
port = 443
scheme = "Http"
}

initial_delay_seconds = 1
period_seconds = 1
failure_threshold = 1
success_threshold = 1
timeout_seconds = 1
}

commands = ["/bin/bash", "-c", "ls"]
}
}
`, data.RandomInteger, data.Locations.Primary, data.RandomInteger, data.RandomInteger)
}

func testCheckAzureRMContainerGroupExists(resourceName string) resource.TestCheckFunc {
return func(s *terraform.State) error {
conn := acceptance.AzureProvider.Meta().(*clients.Client).Containers.GroupsClient
Expand Down
18 changes: 15 additions & 3 deletions website/docs/r/container_group.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -188,11 +188,23 @@ A `volume` block supports:

* `read_only` - (Optional) Specify if the volume is to be mounted as read only or not. The default value is `false`. Changing this forces a new resource to be created.

* `storage_account_name` - (Required) The Azure storage account from which the volume is to be mounted. Changing this forces a new resource to be created.
* `storage_account_name` - (Optional) The Azure storage account from which the volume is to be mounted. Changing this forces a new resource to be created.

* `storage_account_key` - (Required) The access key for the Azure Storage account specified as above. Changing this forces a new resource to be created.
* `storage_account_key` - (Optional) The access key for the Azure Storage account specified as above. Changing this forces a new resource to be created.

* `share_name` - (Required) The Azure storage share that is to be mounted as a volume. This must be created on the storage account specified as above. Changing this forces a new resource to be created.
* `share_name` - (Optional) The Azure storage share that is to be mounted as a volume. This must be created on the storage account specified as above. Changing this forces a new resource to be created.

* `git_repo` - (Optional) A `git_repo` block as defined below.

---

The `git_repo` block supports:

* `url` - (Required) Specifies the Git repository to be cloned. Changing this forces a new resource to be created.

* `directory` - (Optional) Specifies the directory into which the repository should be cloned. Changing this forces a new resource to be created.

* `revision` - (Optional) Specifies the commit hash of the revision to be cloned. If unspecified, the HEAD revision is cloned. Changing this forces a new resource to be created.

---

Expand Down